【发布时间】:2021-07-13 10:35:00
【问题描述】:
我知道很多开发人员过去都遇到过类似的问题。我经历了其中的大部分,但无法解决问题。
我正在尝试更新购物车上下文计数器值。以下是代码(store/userCartContext.js 文件)
import React, { createContext, useState } from "react";
const UserCartContext = createContext({
userCartCTX: [],
userCartAddCTX: () => {},
userCartLength: 0
});
export function UserCartContextProvider(props) {
const [userCartStore, setUserCartStore] = useState([]);
const addCartProduct = (value) => {
setUserCartStore((prevState) => {
return [...prevState, value];
});
};
const userCartCounterUpdate = (id, value) => {
console.log("hello dolly");
// setTimeout(() => {
setUserCartStore((prevState) => {
return prevState.map((item) => {
if (item.id === id) {
return { ...item, productCount: value };
}
return item;
});
});
// }, 50);
};
const context = {
userCartCTX: userCartStore,
userCartAddCTX: addCartProduct,
userCartLength: userCartStore.length,
userCartCounterUpdateCTX: userCartCounterUpdate
};
return (
<UserCartContext.Provider value={context}>
{props.children}
</UserCartContext.Provider>
);
}
export default UserCartContext;
这里我已经注释掉了setTimeout 函数。如果我使用 setTimeout,它会完美运行。但我不确定这是否正确。
在cartItemEach.js 文件中,我使用以下代码更新上下文
const counterChangeHandler = (value) => {
let counterVal = value;
userCartBlockCTX.userCartCounterUpdateCTX(props.details.id, counterVal);
};
CodeSandBox 链接:https://codesandbox.io/s/react-learnable-one-1z5td
当我更新 CART 弹出窗口中的计数器时会出现问题。如果只更新一次计数器,就不会出现任何错误。但是,当您多次更改计数器时,控制台内会弹出此错误。即使出现此错误,它也不会影响整个代码。更新后的计数器值存储在 Context 中的状态中。
【问题讨论】:
-
您在控制台中看到的错误是什么?
-
@DanielBeck,我已经更新了 CodeSandBox 链接。我得到的警告是——警告:在渲染不同的组件 (
Counter) 时无法更新组件 (UserCartContextProvider)。要在Counter中找到错误的 setState() 调用, -
@DanielBeck 我认为问题出在 counter.js 文件(组件 > counter.js)中,我使用
props.onCounterChange();将值传递回父组件 -
@DanielBeck 目前我正在修改计数器组件。我使用对象解构
const Counter = ({counterType,currentCounterVal,onCartBtnPush,onCounterChange}) => {}而不是道具,而不是在incrementHandler()和decrementHandler()中调用函数onCounterChange()我正在使用这样的 useEffectuseEffect(()=>{ onCounterChange(number); },[number, onCounterChange])但这也不起作用 -
请显示
userCartCounterUpdateCTX的调用位置。可能需要用useEffect或类似名称进行包装。
标签: reactjs react-context