useEffect导致具有常量依赖关系的无限循环



useEffect被触发,即使依赖数组有常量对象。

我尝试提取逻辑并将对象放入useState

const payload = {
limit: 5,
offset: 0,
filterBy: 'All',
};
useEffect(() => {
const defaultPayload = {
limit: 10,
offset: 0,
filterBy: 'All',
};
dispatch({ type: RANDOM_CONST, payload: payload || defaultPayload });
}, [dispatch, payload]);

它应该只在payload发生变化时触发。由于payload是一个常数,所以它应该只运行一次,并记录无限次。

有两个问题可能会导致重新渲染,请注意useEffectdep-array值进行了浅比较

  1. payload在每次渲染中都是一个新对象,因此oldPayload === payload始终为false,导致useEffect运行。

  2. 如果dispatch来自第三方库(如react redux hook(,则它可能会在每个渲染上生成新的dispatch引用,因此oldDispatch === dispatch再次离开false并导致useEffect运行。

要修复它,可以将"常量对象"移动到外部作用域(将运行一次(,如果传递dispatch,则使用useCallback钩子。

react-redux文档中的示例:当使用dispatch将回调传递给子组件时,建议使用useCallback对其进行内存化,因为否则子组件可能会由于引用更改而不必要地进行渲染。

const payload = {
limit: 5,
offset: 0,
filterBy: 'All'
};
const App = () => {
//                   v Memoize it if passing as a callback,
//                     check in library docs if there is a new instance
//                     on every render
const dispatch = useDispatch();
useEffect(() => {
dispatch({ type: RANDOM_CONST, payload });
}, []);
return;
};

注意:没有任何迹象表明dispatch函数来自何处。

您可以将对象转换为JSON字符串,并在useEffect挂钩中进行比较:

JSON.stringify(oldValue) === JSON.stringify(newValue) // true

请注意,对象键应具有相同的顺序:

JSON.stringify({a: 1, b: 2}) === JSON.stringify({a: 1, b: 2}) // true
JSON.stringify({a: 1, b: 2}) === JSON.stringify({b: 2, a: 1}) // false

相关内容

  • 没有找到相关文章

最新更新