无法从我的购物车中移除(无法在呈现不同组件时更新组件)
Cannot remove from my shopping cart (Cannot update a component while rendering a different component)
我正在制作购物车,但我 运行 出错了,消息准确地说:警告:无法更新组件 (StateProvider
) 同时呈现不同的组件(CartDrinks
)。在 CartDrinks
中找到错误的 setState() 调用。我正在使用 React Context 来做这件事,但我可以找到解决方案。
这是我的上下文:
import { createContext, useContext, useReducer } from "react";
export const StateContext = createContext();
export const StateProvider = ({ reducer, initialState, children }) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
)
export const useStateValue = () => useContext(StateContext);
这是我的 Reducer:
export const initialState = {
cart: [],
}
const reducer = (state, action) => {
console.log(action)
switch (action.type) {
case "ADD_TO_CART":
return {
...state,
cart: [...state.cart, action.payload]
};
case "REMOVE_TO_CART":
let newCart = [...state.cart];
const index = state.cart.findIndex((cartItems) => cartItems.id === action.payload.id);
newCart.splice(index, 1);
if (index >= 0) {
newCart.splice(index, 1);
} else {
alert('Cant remove drink');
}
return { ...state, cart: newCart };
default:
return state;
}
}
export default reducer;
这是我将产品添加到购物车的组件:
import { useStateValue } from '../../context/Context';
import './card.css'
const Card = ({ id, name, image, price }) => {
const [{ }, dispatch] = useStateValue();
const addToCard = () => {
dispatch({
type: 'ADD_TO_CART',
item: {
id: id,
name: name,
image: image,
price: price,
}
})
}
return (
<div className="card">
<img src={image} alt={image} />
<div className="card__body">
<h3>{name}</h3>
<p>Price: $/.{price}</p>
</div>
<button onClick={addToCard}>Add to Cart</button>
</div>
)
}
export default Card
这是我从购物车中删除产品的组件
import { useStateValue } from "../../context/Context"
import './cart.css'
const CartDrinks = () => {
const [{ cart }, dispatch] = useStateValue();
const removeDrink = (id) => {
dispatch({
type: "REMOVE_TO_CART",
id: id
})
}
return (
<div className="cart__container">
{cart?.length === 0
?
<p>You don't have nothing</p>
:
cart.map((i) => (
<div className="cart" key={i.id}>
<img src={i.image} alt="" />
<div>
<h4>{i.name}</h4>
<p>$/.{i.price}</p>*
<button onClick={removeDrink(i.id)}>remove</button>
</div>
</div>
))
}
</div>
)
}
export default CartDrinks
一切正常,直到我尝试进入我删除产品的组件,进入该组件时出现错误。
挂载 CartDrinks
组件时立即调用 removeDrink
函数。
const removeDrink = (id) => {
dispatch({
type: "REMOVE_TO_CART",
id: id
})
}
...
<button onClick={removeDrink(i.id)}>remove</button> // <-- immediate call
单击时使用匿名回调调用 removeDrink
。
<button onClick={() => removeDrink(i.id)}>remove</button>
或将 removeDrink
转换为柯里化函数以关闭 id
和 return 回调。
const removeDrink = (id) => () => {
dispatch({
type: "REMOVE_TO_CART",
id: id
})
}
...
<button onClick={removeDrink(i.id)}>remove</button>
我正在制作购物车,但我 运行 出错了,消息准确地说:警告:无法更新组件 (StateProvider
) 同时呈现不同的组件(CartDrinks
)。在 CartDrinks
中找到错误的 setState() 调用。我正在使用 React Context 来做这件事,但我可以找到解决方案。
这是我的上下文:
import { createContext, useContext, useReducer } from "react";
export const StateContext = createContext();
export const StateProvider = ({ reducer, initialState, children }) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
)
export const useStateValue = () => useContext(StateContext);
这是我的 Reducer:
export const initialState = {
cart: [],
}
const reducer = (state, action) => {
console.log(action)
switch (action.type) {
case "ADD_TO_CART":
return {
...state,
cart: [...state.cart, action.payload]
};
case "REMOVE_TO_CART":
let newCart = [...state.cart];
const index = state.cart.findIndex((cartItems) => cartItems.id === action.payload.id);
newCart.splice(index, 1);
if (index >= 0) {
newCart.splice(index, 1);
} else {
alert('Cant remove drink');
}
return { ...state, cart: newCart };
default:
return state;
}
}
export default reducer;
这是我将产品添加到购物车的组件:
import { useStateValue } from '../../context/Context';
import './card.css'
const Card = ({ id, name, image, price }) => {
const [{ }, dispatch] = useStateValue();
const addToCard = () => {
dispatch({
type: 'ADD_TO_CART',
item: {
id: id,
name: name,
image: image,
price: price,
}
})
}
return (
<div className="card">
<img src={image} alt={image} />
<div className="card__body">
<h3>{name}</h3>
<p>Price: $/.{price}</p>
</div>
<button onClick={addToCard}>Add to Cart</button>
</div>
)
}
export default Card
这是我从购物车中删除产品的组件
import { useStateValue } from "../../context/Context"
import './cart.css'
const CartDrinks = () => {
const [{ cart }, dispatch] = useStateValue();
const removeDrink = (id) => {
dispatch({
type: "REMOVE_TO_CART",
id: id
})
}
return (
<div className="cart__container">
{cart?.length === 0
?
<p>You don't have nothing</p>
:
cart.map((i) => (
<div className="cart" key={i.id}>
<img src={i.image} alt="" />
<div>
<h4>{i.name}</h4>
<p>$/.{i.price}</p>*
<button onClick={removeDrink(i.id)}>remove</button>
</div>
</div>
))
}
</div>
)
}
export default CartDrinks
一切正常,直到我尝试进入我删除产品的组件,进入该组件时出现错误。
挂载 CartDrinks
组件时立即调用 removeDrink
函数。
const removeDrink = (id) => {
dispatch({
type: "REMOVE_TO_CART",
id: id
})
}
...
<button onClick={removeDrink(i.id)}>remove</button> // <-- immediate call
单击时使用匿名回调调用 removeDrink
。
<button onClick={() => removeDrink(i.id)}>remove</button>
或将 removeDrink
转换为柯里化函数以关闭 id
和 return 回调。
const removeDrink = (id) => () => {
dispatch({
type: "REMOVE_TO_CART",
id: id
})
}
...
<button onClick={removeDrink(i.id)}>remove</button>