Javascript UseEffect调用的UseState不';t使用Set方法更新变量
以代码为例:Javascript UseEffect调用的UseState不';t使用Set方法更新变量,javascript,reactjs,react-hooks,use-effect,use-state,Javascript,Reactjs,React Hooks,Use Effect,Use State,以代码为例: import React, { useState, useEffect } from 'react'; ........ More stuff const ProductContext = React.createContext(); const ProductConsumer = ProductContext.Consumer; const ProductProvider = ({ children }) => { const [state, setState] =
import React, { useState, useEffect } from 'react';
........ More stuff
const ProductContext = React.createContext();
const ProductConsumer = ProductContext.Consumer;
const ProductProvider = ({ children }) => {
const [state, setState] = useState({
sideBarOpen: false,
cartOpen: true,
cartItems: 10,
links: linkData,
socialIcons: socialData,
cart: [],
cartSubTotal: 0,
cartTax: 0,
cartTotal: 0,
.......
loading: true,
cartCounter: 0,
});
const getTotals = () => {
// .. Do some calculations ....
return {
cartItems,
subTotal,
tax,
total,
};
};
const addTotals = () => {
const totals = getTotals();
setState({
...state,
cartItems: totals.cartItems,
cartSubTotal: totals.subTotal,
cartTax: totals.tax,
cartTotal: totals.total,
});
};
/**
* Use Effect only when cart has been changed
*/
useEffect(() => {
if (state.cartCounter > 0) {
addTotals();
syncStorage();
openCart();
}
}, [state.cartCounter]);
..... More code
return (
<ProductContext.Provider
value={{
...state,
............... More stuff
}}
>
{children}
</ProductContext.Provider>
);
};
export { ProductProvider, ProductConsumer };
并更新状态,但是设置状态
功能不更新状态
运行时:
setState({
...state,
cartItems: totals.cartItems,
cartSubTotal: totals.subTotal,
cartTax: totals.tax,
cartTotal: totals.total,
});
在addTotals
内部,即使在UseEffect检测到状态时自动调用此函数。cartCounter
已更改
为什么更改没有反映在
状态变量中?没有精简的工作示例,我只能猜测问题
潜在问题1
您正在调用useffect
中的回调函数,该函数应添加到它的[依赖项]
中以备记忆
const dep2=React.useCallback(()=>{},[]);
useffect(()=>{
如果(dep1>0){
dep2();
}
},[dep1,dep2]);
由于dep2
是一个回调函数,如果它没有包装在React.useCallback
中,那么如果它被更改,可能会导致无限重渲染
潜在问题2
您正在更改状态对象或其属性之一。由于我没有看到完整的代码,这只是一个假设。但是数组方法,如:splice
,push
,unshift
,shift
,pop
,sort
,列举了一些导致原始数组突变的方法。此外,对象可以通过使用delete prop
或obj.name=“example”
或obj[“total”]=2进行变异。同样,没有完整的代码,这只是一个猜测
潜在问题3
执行时,您正试图传播过时状态。当使用多个setState
调用来更新对象时,不能保证状态在执行时是最新的。最佳做法是向setState传递一个函数,该函数接受当前状态作为参数,并返回更新的状态对象:
setState(prevState=>({
…国家,
prop1:prevState.prop1+1
}));
这确保了在批处理执行时状态始终是最新的。例如,如果第一个设置状态更新了cartotal:11
,则执行下一个设置状态时,prevState.cartotal
保证为11
潜在问题4
如果state.cartCounter
在此组件中进行过更新,则这将导致无限重渲染循环,因为useffect
会在每次更改时侦听并激发这可能是项目中的问题,也可能不是问题,但需要注意。解决方法是触发布尔值,以防止addTotals
执行多次。由于道具名称“cartCounter”是一个数字,对其整体功能而言相当模糊,因此它可能不是同步更新购物车总数的最佳方式
React.useffect(()=>{
if(state.cartCounter>0&&state.updateCart){
addTotals();
等
}
},[state.updateCart、state.cartCounter、addTotals]);
工作演示(单击添加到购物车
按钮更新购物车状态):
如果上面提到的两个问题都不能解决您的问题,那么我建议创建一个。否则,这是一个猜测游戏。@saruunk:这是react hooks,而不是类组件的SetState。我甚至可以称之为setJanetJackson
,没有区别。你是说上述方法行不通吗?@saruunk:我们在功能组件中没有这个
!这种方法在这里不起作用。@SarunUK:谢谢你的帮助,我知道如何使用谷歌,但这个链接并不能解决上述问题。
setState({
...state,
cartItems: totals.cartItems,
cartSubTotal: totals.subTotal,
cartTax: totals.tax,
cartTotal: totals.total,
});