为什么 React 函数引用在每次渲染时都不会改变?

Why react function reference doesn't change at every render?

这里是 React 学习者。

我创建了一个新的 React redux typescript 应用程序:

npx create-react-app my-app --template redux-typescript

在示例代码中,我添加了一个 useEffect 以仅在组件第一次呈现时分派一次操作:

在src\features\counter\Counter.tsx

   const dispatch = useAppDispatch();
   
   ...
 
  useEffect(() => {
     dispatch(increment())
  }, [dispatch]);

我还添加了另一个按钮来更改此组件中的新状态,以强制重新呈现组件,并确保只调用一次 useEffect 代码。

问题是一切正常,但我不明白一件事。

我了解到(确定我遗漏了一些东西)在每个渲染周期中,“调度”函数应该被重新定义。所以每个渲染周期“调度”应该有不同的参考,这应该再次触发 useEffect。

但这并没有发生。

看起来在每次渲染“调度”时都不会更改引用(否则将再次调用 useEffect),但这怎么可能?我错过了什么?

我很困惑,因为如果我像这样创建自定义挂钩:

const useRequestHook = () => {
 
  const sendRequest =useCallback(() => {
      console.log("send request invoked")
  }, []);

  return sendRequest;

};

export default useRequestHook;

如果我在 Counter 组件中使用它:


      const sendRequest = useRequestHook();
    
      useEffect(() => {
        sendRequest();
      }, [sendRequest]);

我在组件再次呈现时遇到问题,例如当我单击按钮时。因为新的render会改变sendRequest的引用,useEffect又会被调用,所以解决方法是把useCallback

包裹起来
 

     import { useCallback } from "react";
    
    const useRequestHook = () => {
     
      const sendRequest =useCallback(() => {
          console.log("send request invoked")
      }, []);
    
      return sendRequest;
    
    };
    
    export default useRequestHook;

现在它按我的理解按预期工作了。

为什么“dispatch”和“sendRequest”的行为不同?

文档:https://react-redux.js.org/api/hooks#usedispatch

This hook returns a reference to the dispatch function from the Redux store.

这是关键。使用自定义挂钩 useAppDispatch 你实际上得到了对调度函数的引用,所以你不会每次都重新创建函数,这就是为什么 useEffect 不会在每个 re-render.