gpt4 book ai didi

javascript - useReducer : dispatch action, 在其他组件中显示状态并在分派(dispatch)操作时更新状态

转载 作者:行者123 更新时间:2023-12-05 03:31:02 27 4
gpt4 key购买 nike

我遇到了一个我无法解决的问题。我正在构建一个电子商务 react 应用程序并使用 useReduceruseContext 进行状态管理。客户打开产品,挑选商品数量,然后单击“添加到购物车”按钮以发送操作。这部分工作正常,问题开始了。我不知道如何在 Navbar.js 组件中显示和更新购物车中的产品总数。它在路线更改后显示,但我希望在单击“添加到购物车”按钮时更新它。我试过 useEffect 但它不起作用。

初始状态是这样的

const initialState = [
{
productName: '',
count: 0
}
]

AddToCart.js 效果很好

import React, { useState, useContext } from 'react'
import { ItemCounterContext } from '../../App'

function AddToCart({ product }) {
const itemCounter = useContext(ItemCounterContext)
const [countItem, setCountItem] = useState(0)

const changeCount = (e) => {
if (e === '+') { setCountItem(countItem + 1) }
if (e === '-' && countItem > 0) { setCountItem(countItem - 1) }
}

return (
<div className='add margin-top-small'>
<div
className='add-counter'
onClick={(e) => changeCount(e.target.innerText)}
role='button'
>
-
</div>

<div className='add-counter'>{countItem}</div>

<div
className='add-counter'
onClick={(e) => changeCount(e.target.innerText)}
role='button'
>
+
</div>
<button
className='add-btn btnOrange'
onClick={() => itemCounter.dispatch({ type: 'addToCart', productName: product.name, count: countItem })}
>
Add to Cart
</button>
</div>
)
}

export default AddToCart

Navbar.js 是我遇到问题的地方

import React, { useContext } from 'react'
import { Link, useLocation } from 'react-router-dom'
import NavList from './NavList'
import { StoreContext, ItemCounterContext } from '../../App'
import Logo from '../Logo/Logo'

function Navbar() {
const store = useContext(StoreContext)
const itemCounter = useContext(ItemCounterContext)
const cartIcon = store[6].cart.desktop
const location = useLocation()
const path = location.pathname

const itemsSum = itemCounter.state
.map((item) => item.count)
.reduce((prev, curr) => prev + curr, 0)

const totalItemsInCart = (
<span className='navbar__elements-sum'>
{itemsSum}
</span>
)

return (
<div className={`navbar ${path === '/' ? 'navTransparent' : 'navBlack'}`}>
<nav className='navbar__elements'>
<Logo />
<NavList />
<Link className='link' to='/cart'>
<img className='navbar__elements-cart' src={cartIcon} alt='AUDIOPHILE CART ICON' />
{itemsSum > 0 ? totalItemsInCart : null}
</Link>
</nav>
</div>
)
}

export default Navbar

最佳答案

问题出在您的 reducer 中,特别是您将先前的状态分配给 newState 以进行突变并返回更新后的状态。在 JavaScript 中,非原始类型是通过地址而不是值来引用的。由于你的 initialState 是一个数组,恰好是一个非原始的,所以当你将一个非原始的分配给一个新变量时,这个变量只指向内存中现有的数组而不会创建一个新副本。而且,在 React 中,仅当状态被重建时(这就是 React 理解存在更新的方式)而不是软变异时才会触发/广播更新。当您改变并返回 newState 时,您基本上改变了现有的 state 而不是导致它重建。一个快速的解决方法是将您的 state 复制到 newState 而不仅仅是分配它。这可以使用扩展运算符 (...) 来完成。
在你的 reducer 函数中,更改:

const newState = state

const newState = [...state]

你的 reducer 函数应该看起来像这样:

export const reducer = (state, action) => {
// returns -1 if product doesn't exist
const indexOfProductInCart = state.findIndex((item) => item.productName === action.productName)
const newState = [...state] //Deep-copying the previous state

switch (action.type) {
case 'increment': {
if (indexOfProductInCart === -1) {
newState[state.length] = { productName: action.productName, count: state.count + 1 }
return newState
}
newState[indexOfProductInCart] = { productName: action.productName, count: state.count + 1 }
return newState
}
case 'decrement': {
if (indexOfProductInCart === -1) {
newState[state.length] = { productName: action.productName, count: state.count - 1 }
return newState
}
newState[indexOfProductInCart] = { productName: action.productName, count: state.count - 1 }
return newState
}
case 'addToCart': {
if (indexOfProductInCart === -1) {
newState[state.length] = { productName: action.productName, count: action.count }
return newState
}
newState[indexOfProductInCart] = { productName: action.productName, count: action.count }
return newState
}
case 'remove': return state.splice(indexOfProductInCart, 1)
default: return state
}
}

关于javascript - useReducer : dispatch action, 在其他组件中显示状态并在分派(dispatch)操作时更新状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70713866/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com