0

我有以下自定义钩子

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);
};
4

1 回答 1

3

如果我正确理解了钩子的目的,它实际上只是对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;
  };
};

它使用选项 type,该选项专为此类情况而设计。如果没有值,我们使用optionsNone值表示,如果有值,我们使用Some. 我们不是使用ifJavaScript 语义上不明确的真实性概念,而是对使用进行模式匹配以发现它和需要计算的值,或者获取值。optionswitchNoneSome

模式匹配的使用option在 Reason 代码中非常常见,因此如果需要,您应该使用上面提供的链接了解更多详细信息。

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

于 2020-05-01T09:07:02.360 回答