在函数中多次调用时,钩子如何工作?

时间:2019-07-03 18:40:34

标签: javascript reactjs react-hooks

为什么true的加载状态从不记录,而是在下面的以下代码和框中异步记录功能?当在函数中调用相同的钩子时,会发生什么?

代码

codesandbox

function App() {
  const [loadingWithUseState, setLoadingWithUseState] = useState(false);
  const [loadingWithReducer, setLoadingWithReducer] = useReducer(
    (acc, next) => ({ ...acc, ...next }),
    { loadingWithReducer: false }
  );

  const onClickWithUseState = () => {
    setLoadingWithUseState(true);
    setLoadingWithUseState(false);
  };

  const onClickWithReducer = () => {
    setLoadingWithReducer({ loadingWithReducer: true });
    setLoadingWithReducer({ loadingWithReducer: false });
  };

  const onClickWithUseStateAsync = async () => {
    setLoadingWithUseState(true);
    await delay();
    setLoadingWithUseState(false);
  };

  const onClickWithReducerAsync = async () => {
    setLoadingWithReducer({ loadingWithReducer: true });
    await delay();
    setLoadingWithReducer({ loadingWithReducer: false });
  };

  useEffect(() => {
    console.log("loadingWithUseState changed to", loadingWithUseState);
  }, [loadingWithUseState]);

  useEffect(() => {
    console.log("loadingWithReducer changed to", loadingWithReducer);
  }, [loadingWithReducer]);

  console.log("re-render", { loadingWithUseState, ...loadingWithReducer });

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={onClickWithUseState}>
        {" "}
        trigger load with useState{" "}
      </button>
      <button onClick={onClickWithReducer}>
        {" "}
        trigger load with useReducer{" "}
      </button>
      <button onClick={onClickWithUseStateAsync}>
        {" "}
        trigger load with async useReducer{" "}
      </button>
      <button onClick={onClickWithReducerAsync}>
        {" "}
        trigger load with async useReducer{" "}
      </button>
    </div>
  );
}

P.S我想建立一个心理模型,说明当您同时调用多个挂钩时会发生什么情况

1 个答案:

答案 0 :(得分:0)

设置状态时,出于性能原因,ReactJS将批处理状态更新。因此,当您依次调用setLoadingWithUseState(true)setLoadingWithUseState(false)时,React会将这两个批处理在一起,因此您将看不到第一个更新。