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
是一个常数,因此它应该只运行一次并记下无限次。
答案 0 :(得分:5)
有两个可能导致重新渲染的问题,请注意useEffect
与dep-array
值进行了浅比较:
payload
是每个渲染上的新对象,因此oldPayload === payload
总是false
,导致useEffect
运行。
如果dispatch
来自第三方库(例如react-redux hook),则可能在每个渲染器上都创建了一个新的dispatch
引用,因此oldDispatch === dispatch
还是离开false
并导致useEffect
运行。
要修复此问题,可以将“常量对象”移到外部作用域(它将运行一次),如果传递useCallback
,请使用dispatch
钩子。
来自
react-redux
docs:的示例在使用分派将回调传递给子组件时,建议使用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
函数的来源没有任何疑问。
答案 1 :(得分:0)
您可以将对象转换为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