【发布时间】:2022-01-14 16:43:49
【问题描述】:
我有一个我无法解决的问题。我正在构建一个电子商务反应应用程序并使用useReducer 和useContext 进行状态管理。客户打开一个产品,选择项目数量,然后单击“添加到购物车”按钮,该按钮调度一个操作。这部分运行良好,问题开始了。我不知道如何在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
【问题讨论】:
-
AddToCart和Navbar似乎在使用不同的上下文。您可以将所有相关代码添加到您的问题中吗?你能分享这些上下文和减速器钩子等......吗?更新上下文值应该足以触发任何上下文使用者使用最新的上下文值重新呈现。 -
我想我看到了你更大的问题......你正在记忆初始状态并且从不更新上下文值。这解释了为什么您的状态没有“更新”,或者更确切地说,为什么消费者看不到更新,以及为什么改变状态会泄漏它们。请参阅我的更新答案。如果您仍然存在问题,请尝试将您的代码分叉到 running 代码框中,我们可以实时检查和调试。
-
您有机会查看更新的答案吗?
-
是的,RTK 是对旧版 react-redux 的卓越改进。
useMemo只是简单地记忆一个值,依赖数组是您想要重新记忆一个值的引用。这通常是为了提供对值的稳定引用,而不是触发不必要的重新渲染。在您的情况下,您使用了一个空的依赖数组,因此记忆值是在初始渲染时计算的,并且从未更新。 RTK 很棒,因为它允许您编写可变的 reducer,并在后台处理不可变性问题,结果是您的 reducer 代码更具逻辑性。 -
现在我明白了。我将console.logs 放在reducer 函数中的任何地方,以找出问题所在,并且效果很好。当 console.logs 返回更新状态时,我感到震惊。确实认为减速器功能是问题所在。状态更新正常,但 useMemo 出现问题。 RTK 比传统的 redux 简单得多,也许我错了,但是 useContext 和 useReducer 似乎比 RTK 更简单。非常感谢!这很有帮助。
标签: javascript reactjs react-hooks react-state-management use-reducer