Redux 状态发生变化但未反映在组件中
Redux state changes but not reflected in component
我正在尝试使用 redux 实现购物车。这是我的购物车减速器:
export const cartReducer = (
state = { cartItems: JSON.parse(localStorage.getItem("cartItems") || "[]")},
action) => {
switch (action.type) {
case ADD_TO_CART:
return { ...state,cartItems: action.payload };
}}
这是我想显示更新状态值的组件,在连接中使用道具访问它并在每次状态更新后更新 cartItems.length
class Cartsidebar extends Component {
constructor(props) {
super(props);
this.state = {
grandTotal: '',toggle:true
}
}
handleHide(){
this.setState({ toggle: !this.state.toggle})
}
render() {
const {cartItems}=this.props;
console.log(cartItems);
return (
<div>
{cartItems.length}
</div>
)
}
}
export default connect(
(state) => ({
cartItems: state.cart.cartItems,
}),
{ incrementToCart, decreaseToCart, removeFromCart }
)(Cartsidebar);
状态更新正常,每次更新 redux 状态时,redux-dev-tools 中也会显示状态差异,但它没有反映在购物车中 component.what 我在这里做错了吗?提前致谢。
编辑:
这是在添加到购物车按钮 onclick 事件时执行的函数:
handleAddToCart=(p)=>{
const cartItems = store.getState().cart.cartItems;
let alreadyExists = false;
cartItems.forEach((x) => {
if (x.discountPer === p.discountPer) {
alreadyExists = true;
}
});
if (!alreadyExists) {
cartItems.push({ ...p });
}
store.dispatch(addToCart(cartItems));
}
addToCart 动作创建器如下所示:
export const addToCart = (cartItem) => {
return({
type: ADD_TO_CART,
payload: cartItem,
});
};
你在 handleAddToCart
中所做的是一个很大的禁忌,并且违背了 Redux 试图强制执行的模式。我对您的逻辑进行了一些更改以使其更容易,并更新了减速器。理论上,如果您进行这些更改,它应该会起作用。
处理添加到购物车:
handleAddToCart = (p) => {
const cartItems = store.getState().cart.cartItems;
for (const item of cartItems) {
if (item.discountPer === p.discountPer) {
return;
}
}
store.dispatch(addToCart({ ...p }));
};
减速器:
export const cartReducer = (
state = { cartItems: JSON.parse(localStorage.getItem("cartItems") || "[]") },
action
) => {
switch (action.type) {
case ADD_TO_CART:
return { ...state, cartItems: [...state.cartItems, action.payload] };
}
};
问题
- 您正在改变状态对象。您正在访问对状态中的购物车数组的引用并直接推入其中。
- 您没有正确利用 Redux 和 reducer 的强大功能。
代码
handleAddToCart = (p) => {
const cartItems = store.getState().cart.cartItems; // cartItems is reference to state
let alreadyExists = false;
cartItems.forEach((x) => {
if (x.discountPer === p.discountPer) {
alreadyExists = true;
}
});
if (!alreadyExists) {
cartItems.push({ ...p }); // mutation!!
}
store.dispatch(addToCart(cartItems));
}
解决方案
在操作中传递您想要添加到购物车的商品,并将所有用于更新购物车的逻辑移动到您的减速器中。
UI
handleAddToCart = (p) => {
this.props.addToCart(p);
}
...
export default connect(
(state) => ({
cartItems: state.cart.cartItems,
}),
{ addToCart, incrementToCart, decreaseToCart, removeFromCart }
)(Cartsidebar);
减速器
case ADD_TO_CART:
const { payload } = action;
const found = state.cartItems.find(item => item.discountPer === payload.discountPer);
if (found) {
return state;
}
return {
...state,
cartItems: state.cartItems.concat(payload),
};
我正在尝试使用 redux 实现购物车。这是我的购物车减速器:
export const cartReducer = (
state = { cartItems: JSON.parse(localStorage.getItem("cartItems") || "[]")},
action) => {
switch (action.type) {
case ADD_TO_CART:
return { ...state,cartItems: action.payload };
}}
这是我想显示更新状态值的组件,在连接中使用道具访问它并在每次状态更新后更新 cartItems.length
class Cartsidebar extends Component {
constructor(props) {
super(props);
this.state = {
grandTotal: '',toggle:true
}
}
handleHide(){
this.setState({ toggle: !this.state.toggle})
}
render() {
const {cartItems}=this.props;
console.log(cartItems);
return (
<div>
{cartItems.length}
</div>
)
}
}
export default connect(
(state) => ({
cartItems: state.cart.cartItems,
}),
{ incrementToCart, decreaseToCart, removeFromCart }
)(Cartsidebar);
状态更新正常,每次更新 redux 状态时,redux-dev-tools 中也会显示状态差异,但它没有反映在购物车中 component.what 我在这里做错了吗?提前致谢。
编辑: 这是在添加到购物车按钮 onclick 事件时执行的函数:
handleAddToCart=(p)=>{
const cartItems = store.getState().cart.cartItems;
let alreadyExists = false;
cartItems.forEach((x) => {
if (x.discountPer === p.discountPer) {
alreadyExists = true;
}
});
if (!alreadyExists) {
cartItems.push({ ...p });
}
store.dispatch(addToCart(cartItems));
}
addToCart 动作创建器如下所示:
export const addToCart = (cartItem) => {
return({
type: ADD_TO_CART,
payload: cartItem,
});
};
你在 handleAddToCart
中所做的是一个很大的禁忌,并且违背了 Redux 试图强制执行的模式。我对您的逻辑进行了一些更改以使其更容易,并更新了减速器。理论上,如果您进行这些更改,它应该会起作用。
处理添加到购物车:
handleAddToCart = (p) => {
const cartItems = store.getState().cart.cartItems;
for (const item of cartItems) {
if (item.discountPer === p.discountPer) {
return;
}
}
store.dispatch(addToCart({ ...p }));
};
减速器:
export const cartReducer = (
state = { cartItems: JSON.parse(localStorage.getItem("cartItems") || "[]") },
action
) => {
switch (action.type) {
case ADD_TO_CART:
return { ...state, cartItems: [...state.cartItems, action.payload] };
}
};
问题
- 您正在改变状态对象。您正在访问对状态中的购物车数组的引用并直接推入其中。
- 您没有正确利用 Redux 和 reducer 的强大功能。
代码
handleAddToCart = (p) => {
const cartItems = store.getState().cart.cartItems; // cartItems is reference to state
let alreadyExists = false;
cartItems.forEach((x) => {
if (x.discountPer === p.discountPer) {
alreadyExists = true;
}
});
if (!alreadyExists) {
cartItems.push({ ...p }); // mutation!!
}
store.dispatch(addToCart(cartItems));
}
解决方案
在操作中传递您想要添加到购物车的商品,并将所有用于更新购物车的逻辑移动到您的减速器中。
UI
handleAddToCart = (p) => {
this.props.addToCart(p);
}
...
export default connect(
(state) => ({
cartItems: state.cart.cartItems,
}),
{ addToCart, incrementToCart, decreaseToCart, removeFromCart }
)(Cartsidebar);
减速器
case ADD_TO_CART:
const { payload } = action;
const found = state.cartItems.find(item => item.discountPer === payload.discountPer);
if (found) {
return state;
}
return {
...state,
cartItems: state.cartItems.concat(payload),
};