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,
    });