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] };
  }
};

问题

  1. 您正在改变状态对象。您正在访问对状态中的购物车数组的引用并直接推入其中。
  2. 您没有正确利用 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),
  };