【问题标题】:How to port following hook to reasonml如何将以下钩子移植到reasonml
【发布时间】:2020-05-02 22:01:43
【问题描述】:

我有以下自定义钩子

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

【问题讨论】:

    标签: reason reason-react


    【解决方案1】:

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

    它使用the option type,它是专门为这种情况设计的。如果没有值,我们使用options None 值表示,如果有值我们使用Some。我们没有使用 if 和 JavaScript 语义不清楚的真实性概念,而是使用 option 上的 pattern match 使用 switch 发现它是 None 并且需要计算值,或者 Some 得到价值。

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

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

    【讨论】:

    • 但是你的答案似乎不是compile
    • 这有什么问题?我在 Reason 游乐场尝试过,但显然 React 或 React 示例在那里被破坏了。不过,它似乎确实通过了类型检查。
    • 另外,如果你依赖副作用,你也不应该使用它,而是useEffect
    • 啊,对不起。 React.RefsetCurrent` 设置后当然不会返回值。它返回unit,所以这也是推断的值。我已经用一个希望能正常工作的答案更新了答案。
    猜你喜欢
    • 2011-02-08
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2017-02-06
    • 1970-01-01
    相关资源
    最近更新 更多