简体   繁体   English

React组件不会随着Redux状态的更改而更新

[英]React component does not update with the change in redux state

I have a cart data in this form 我有这种形式的购物车数据

const cart = {
  '1': {
    id: '1',
    image: '/rice.jpg',
    price: 32,
    product: 'Yellow Corn',
    quantity: 2,
  },
  '2': {
    id: '2',
    image: '/rice.jpg',
    price: 400,
    product: 'Beans',
    quantity: 5,
  },

  '3': {
    id: '3',
    image: '/rice.jpg',
    price: 32,
    product: 'Banana',
    quantity: 1,
  },
};

In the reducer file I have a function removeItem that is being consumed by the reducer 在化removeItem器文件中,我有一个由reducer使用的removeItem函数。

const removeItem = (items, id) => {
  items[id] && delete items[id];
  return items;
};

case REMOVE_ITEM: {
  const { cart } = state;
  const {
    payload: { id },
  } = action;

  return {
    ...state,
    cart: removeItem(cart, id),
  };
}

In the component I am using this handleRemove() to handle the deletion 在组件中,我正在使用此handleRemove()处理删除

handleRemove = id => {
  const {
    actions: { removeItem },
  } = this.props;
  const payload = { id };
  removeItem(payload);
};

Now in the redux developer tool, the change is working effectively but the component view is not updating. 现在,在redux开发人员工具中,更改正在有效地起作用,但是组件视图没有更新。

Change removeItem function to below code 将removeItem函数更改为以下代码

const removeItem = (items, id) => {
    items[id] && delete items[id];
    return {...items};
};

This is because component gets change only if reference changes. 这是因为仅当引用发生更改时组件才会更改。 You can refer this link for more explanation 您可以参考链接以获取更多说明

You need to create a copy of the cart, as otherwise React won't detect the change, because it does reference comparison and you return the same object. 您需要创建购物车的副本,否则React不会检测到更改,因为它会进行引用比较,并且您返回相同的对象。 Try to do the removeItem() in this way. 尝试以这种方式执行removeItem()

const removeItem = (items, id) => {
    let itemsClone = [...items]; // Copies all items into a brand new array
    itemsClone [id] && delete itemsClone [id]; // You perform the delete on the clone
    return itemsClone ; // you return the clone
};

Do not mutate redux state, redux does not perform a deep diff check in your objects, when you do not mutate and create new objects, it is automatically detected as a different object, because its plain old js objects. 不要更改redux状态,redux不会对您的对象执行深度差异检查,当您不更改并创建新对象时,它会自动检测为其他对象,因为它是普通的旧js对象。

this would be good for further reading : immutable-update-patterns 这将有助于进一步阅读: immutable-update-patterns

so your removeItem method should be, 所以您的removeItem方法应该是

const removeItem = (items, id) => {
    let {[id]: remove, ...rest} = items
    return rest;
}

You can also use a library to do this, such as dot-prop-immutable , which has set , remove , merge methods to do relevant operations without mutating the object. 您也可以使用一个库来做到这一点,例如dot-prop-immutable ,它具有setremovemerge方法来执行相关操作而无需更改对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM