可重用的React钩子函数的异常行为?或者我在做什么错?

时间:2018-11-18 11:20:16

标签: reactjs react-hooks

我正在尝试编写自己的可重用useEffect钩子函数useEffectOnce(),使其仅运行一次(在挂载和卸载时),但这似乎是不可能的。每次重新渲染后都会调用我的函数:https://codesandbox.io/s/mjx452lvox

function useEffectOnce() {
  console.log("I am in useEffectOnce");

  useEffect(() => {
    console.log("I am in useEffectOnce's useEffect");
    return () => {
      console.log("i am leaving useEffectOnce's useEffect");
    };
  }, []);
}

function App() {
  const [count, setCount] = useState(0);

  useEffectOnce(); // once!?

  return (
    <div className="app">
      <h3>useEffectOnce (my reusable function)... Wait, once!?</h3>
      <button onClick={() => setCount(count + 1)}>
        You clicked me {count} times
      </button>
    </div>
  );
}

注释:

  • useEffectOnce()内的 useEffect()钩按预期工作
  • useEffectOnce(() => {}, []);不变

...然后令人惊讶的是,具有可重复使用的useState钩子函数(!?)的行为相同:https://codesandbox.io/s/2145m37xnr

每次重新渲染后都会调用我的函数useButton,并且在第一次独立单击时单击该按钮。

function useButton(initialCounterValue) {
  const [usebuttoncount, setUseButtonCount] = useState(initialCounterValue);

  console.log("I am in useButton");

  const handleuseButtonClick = () => {
    setUseButtonCount(usebuttoncount + 1);
  };

  return {
    usebuttoncount,
    onClick: handleuseButtonClick
  };
}

function App() {
  const [count, setCount] = useState(0);
  const useButtonCounter = useButton(0);

  return (
    <div className="app">
      <h3>
        useButton (my reusable useState function) is called only when... OMG!?
      </h3>
      <button onClick={() => setCount(count + 1)}>
        You clicked me {count} times
      </button>
      <br />
      <button {...useButtonCounter}>
        (useButton hook) You clicked me {useButtonCounter.usebuttoncount} times
      </button>
    </div>
  );
}

1 个答案:

答案 0 :(得分:1)

useEffectOnceuseButton是常规函数。它们应在每个组件渲染器上运行。调用组件函数时,无法阻止通过常规JavaScript手段(即不使用eval)来调用它们。

它是useEffect回调函数(I am in useEffectOnce's useEffect日志条目),有望在组件安装时被调用一次。所有需要在组件安装时评估的代码都应驻留在此处。