ReasonML 中的 useEffect 与 useEffect0

idk*_*kjs 4 reason reason-react use-effect

我试图了解两者之间的区别:

 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));
  });
Run Code Online (Sandbox Code Playgroud)

它们都具有相同的类型签名并且都编译但useEffect0什么都不做:

// useEffect0 : unit => option(unit => unit) => unit
// useEffect : unit => option(unit => unit) => unit
Run Code Online (Sandbox Code Playgroud)

要使用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>;
};
Run Code Online (Sandbox Code Playgroud)

删除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>;
};
Run Code Online (Sandbox Code Playgroud)

那么为什么在使用不同的结构时调用会发生变化呢?

任何链接或解释将不胜感激。

谢谢你。

Joh*_*ohn 7

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

不同之处在于[]JavaScript 中插入的第二个参数。默认情况下,useEffect在 JavaScript 中,每次渲染都会触发。通过在第二个参数中添加空数组,我们告诉 React 在组件第一次渲染时只触发一次。