如何将以下钩子移植到 reasonml

How to port following hook to reasonml

我有以下自定义挂钩

function useConstant(fn) {
  const ref = React.useRef()

  if (!ref.current) {
    ref.current = fn()
  }

  return ref.current
}

似乎很难将其移植到 reasonml,我必须使用类型转换两次,理想的方法是什么?

external toAny: 'a => 'b = "%identity";
external toBool: 'a => bool = "%identity";

let useConstant = (fn: unit => 'a) => {
  let ref: React.Ref.t('a) = toAny(React.useRef());
  if (!toBool(React.Ref.current(ref))) {
    React.Ref.setCurrent(ref, fn());
  };
  React.Ref.current(ref);
};

如果我正确理解钩子的用途,它实际上只是 React.useMemo 的重新实现。但是为了学习,这里有一个应该可行的实现。

let useLazy = (fn: unit => 'a): 'a => {
  let ref = React.useRef(None);

  switch (React.Ref.current(ref)) {
  | Some(value) => value
  | None =>
    let value = fn();
    React.Ref.setCurrent(ref, Some(value));
    value;
  };
};

option上使用the option type, which is specifically designed for cases like this. If there's no value, we represent that using options None value, and if there is a value we use Some. Instead of using if with JavaScript's semantically unclear concept of truthiness, we pattern match使用switch发现是None需要计算值,或者Some得到在价值。

option 和模式匹配的使用在 Reason 代码中非常常见,因此您应该真正尝试理解它,如果需要,请使用上面提供的链接以获取更多详细信息。

请注意,您也可以为此使用 Lazy。但这不太常用,因此学习起来也不太有用。