useEffect与useEffect0在ReasonML中的区别

4
我正在尝试理解以下两者之间的区别:
 React.useEffect(() => {
    let timerId = Js.Global.setInterval(() => tick(), 1000);
    Some(() => Js.Global.clearInterval(timerId));
  });
 React.useEffect0(() => {
    let timerId = Js.Global.setInterval(() => tick(), 1000);
    Some(() => Js.Global.clearInterval(timerId));
  });

他们的类型签名相同,都可以编译通过,但是 useEffect0 什么也不做:
// useEffect0 : unit => option(unit => unit) => unit
// useEffect : unit => option(unit => unit) => unit

要使用https://reasonml.github.io/reason-react/blog/2019/04/10/react-hooks中的示例,它使用useEffect,但如果您更改为使用useState而不是useReducer,则必须将useEffect更改为useEffect0

使用useEffect0的原始版本:

type action =
  | Tick;

type state = {
  count: int,
};

[@react.component]
let make = () => {
  let (state, dispatch) = React.useReducer(
    (state, action) =>
      switch (action) {
      | Tick => {count: state.count + 1}
      },
    {count: 0}
  );

  React.useEffect0(() => {
    let timerId = Js.Global.setInterval(() => dispatch(Tick), 1000);
    Some(() => Js.Global.clearInterval(timerId))
  });

  <div>{ReasonReact.string(string_of_int(state.count))}</div>;
};

移除useReducer并使用useEffect后:

[@react.component]
let make = () => {
let (state, dispatch) = React.useState(()=>
    {count: 0}
  );
let tick =()=> dispatch(_=>{count: state.count + 1});
  React.useEffect(() => {
    let timerId = Js.Global.setInterval(() => tick(), 1000);
    Some(() => Js.Global.clearInterval(timerId))
  });

  <div>{ReasonReact.string(string_of_int(state.count))}</div>;
};

当使用不同的结构时,为什么调用会发生变化?
非常感谢任何链接或解释。
谢谢。
1个回答

8

React.useEffect(f) 在 Reason 中编译为 React.useEffect(f) 在 JavaScript 中。 React.useEffect0(f) 在 Reason 中编译为 React.useEffect(f, []) 在 JavaScript 中。

区别在于第二个 JavaScript 中插入的空数组 [] 参数。默认情况下,JavaScript 中的 useEffect 每次渲染都会触发。通过在第二个参数中添加空数组,我们告诉 React 仅当组件首次渲染时才触发它。


谢谢你的回答。所以第一个例子 useEffect0 只会触发一次,并且只会执行一次 useReducer 中的内容,这里是 Tick。在 hook 的例子中,由于添加了空数组,useEffect 会触发一次 tick()。这样说清楚了吗? - armand
请参见 reason.chat 的回答。 - armand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接