如何在不改变数据的情况下改变React Redux中的状态?

时间:2018-05-19 16:46:09

标签: javascript reactjs redux immutable.js

我知道"神圣的"如果处理不当,数据是多么危险;这就是为什么在我的应用程序中,我现在需要处理一个嵌套的长JSON对象(它表示我的应用程序状态)并且我已经很头疼了以及需要修改的节点/值。我想包括Immutable.js。现在的问题是:我如何调整我的减速器,动作,状态等?

这是我的状态摘录,来自MongoDB数据库:

"shops": [
        {
            "shopId": "5a0c67e9fd3eb67969316cff",
            "picture": "http://placehold.it/150x150",
            "name": "Zipak",
            "email": "leilaware@zipak.com",
            "city": "Rabat",
            "location": {
                "type": "Point",
                "coordinates": [
                    -6.74736,
                    33.81514
                ]
            }
        },
        {
            "shopId": "5a0c6b55fd3eb67969316d9d",
            "picture": "http://placehold.it/150x150",
            "name": "Genekom",
            "email": "leilaware@genekom.com",
            "city": "Rabat",
            "location": {
                "type": "Point",
                "coordinates": [
                    -6.74695,
                    33.81594
                ]
            }
        },
        ...

当触发某个操作(最终用户点击"喜欢"按钮)时,我需要向相关的Shop对象添加属性,这样它就会变得像这样:

{
    "shopId": "5a0c67e9fd3eb67969316cff",
    "picture": "http://placehold.it/150x150",
    "name": "Zipak",
    "email": "leilaware@zipak.com",
    "city": "Rabat",
    "liked": true,
    "location": {
        "type": "Point",
        "coordinates": [
            -6.74736,
            33.81514
        ]
    }
},

现在,我设法将liked属性添加到单个Shop对象,但是当我想要更改/修改状态(所有Shop个对象的组)时,我得到了对象重复(具有liked属性的新对象和旧属性)。为了避免这种混乱,我想使用Immutable.js来处理这些操作,以确保一切都干净整洁。

我从哪里开始?我是否将状态转换为Immutable.js地图?列表?

2 个答案:

答案 0 :(得分:0)

您可以使用具有immutability-helper函数的update而不是使用Immutable.js,而不会改变原始值,而是返回更新后的值。

immutability-helper的语法灵感来自MongoDB,所以习惯它对你来说不是很难。

对于您的情况,您可以使用以下示例

修改您的州
import update from 'immutability-helper';

const id = '5a0c67e9fd3eb67969316cff'; // id of the item you need to update
const newState = update(state, {
  shops: {
    $apply: (item) => {
      if (item.shopId !== id) return item
      return {
        ...item,
        liked: true
      }
    }
  }
});

答案 1 :(得分:0)

只需将已识别商店的数量减少到获取成功的对象即可。对于任何唯一项目列表来说,这是一个很好的做法,可以避免查找函数的O(n)复杂性并以更简单的方式改变您的状态。

减少商店在您的商店减速机取得成功:

shops.reduce((obj, item) => {
    obj[item.id] = item
        return obj;
}, {})

然后,您可以轻松地在商店减速机内操作您的物品,例如类似的成功:

return { 
    ...state, 
   [action.shopId]: { 
       ...state[action.shopId], 
       liked: true,
    },
}