为什么 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.
这里是 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.