next.js 状态更改时导航栏组件未重新呈现

esbemjvw  于 2023-06-22  发布在  其他
关注(0)|答案(2)|浏览(151)

我正在尝试创建一个购物车。我已经创建了一个上下文,并在按下购物车上的递增和递减按钮时将状态作为一个值传递给我,我在购物车中的项目计数正在改变,但当我在导航栏组件中使用相同的上下文时,购物车中的项目总数没有改变。我在下面附上代码片段
这是我创建我的上下文的地方

const initialState:initialType = {
  cartItems:cartItems,
  totalItems:cartItems.reduce((accumulator, object) => {
    return accumulator + object.quantity
  }, 0),
  totalAmount:0
}

export const CartContext = createContext<initialType|null>(initialState);

下面是我的useContext提供程序。

<CartContext.Provider value={{...state}}>
<ContextCart removeItems={removeItems} increment={increment} decrement={decrement}/> </CartContext.Provider>

state的值来自useReducer,它正在更新所有内容
这就是我如何在导航栏中使用useContext钩子来获取购物车中的物品总数

const cartItems = useContext(CartContext);

return (
  <div>{cartItems.totalItems}</div>`
)

但是每当状态改变时,导航栏永远不会重新呈现购物车中更新的项目总数,请帮助我。
这是我的useReducer函数,它很好地更新了一切。我已经通过执行console.log()检查了它的功能。它会很好地返回所有东西,包括state.totalItems。

type actionType={
      type:string,
      payload:string
    }
    export const reducer = (state:initialType ,action:actionType) => {
      if(action.type === "Delete" ){
        return {
          ...state,
          cartItems:state.cartItems.filter((currentElement)=>{
            return currentElement.id != action.payload
          })
        }
      }
       if (action.type === 'increment'){
          state.cartItems.forEach((element)=>{
            if (element.id === action.payload){
              element.quantity++;
              state.totalItems++
            }
          })
         
          return {...state};
          
      }
      if (action.type === 'decrement'){
        state.cartItems.forEach((element)=>{
          if (element.id === action.payload){
            element.quantity--;
            state.totalItems--;
          }
        })
        console.log(state)
        return {...state};
      }
      return {...state};
    }```
dvtswwa3

dvtswwa31#

您遇到的问题可能是因为cartItems状态更改时totalItems没有更新。
您可以看到,您只计算一次totalItems,在初始状态设置期间。因此,即使cartItems稍后更改,totalItems也不会重新计算。
一个简单的修复方法是将totalItems计算移到reducer函数中。这样,每次调度操作时都会重新计算。

function cartReducer(state, action) {
  // your action cases here...

  // After performing the action, recalculate totalItems
  const totalItems = state.cartItems.reduce((accumulator, object) => {
    return accumulator + object.quantity
  }, 0);

  return {
    ...state,
    totalItems,
  };
}

不要忘记在递增和递减函数中分派'INCREMENT'和'DECREMENT'操作。
通过此调整,您的totalItems应该与cartItems保持同步,并且您的导航栏应该正确更新。给予看!

q43xntqr

q43xntqr2#

当你使用useReducer时,它会返回当前状态,对吗?在你的例子中,这个状态是一个对象。所以,你可以直接从这个状态对象中获取totalItems。例如:

const [state, dispatch] = useReducer(cartReducer, initialState);

// Here's where we get totalItems from the state
const { totalItems } = state;

因此,这样,totalItems就从状态对象中提取出来了,您可以在任何需要它的地方使用它。

相关问题