【问题标题】:Redux Reducer: Update object in array by key immutablyRedux Reducer:通过键不可变地更新数组中的对象
【发布时间】:2020-01-04 16:43:47
【问题描述】:

问题:用 key = 1 更新 devData 数组中的对象:-> 更新 data 和 dateTime强>

//Redux state:
{
    info: {
        success: true,
        devData: [
            {
                key: 1,
                data: {            <- update this
                    power: 48 ,
                    unit: "kWh"
                },
                dateTime: "2019-08-24T18:21:21.000Z"  <- update this
            },
            {
                key: 2,
                data: {
                    power: 48,
                    unit: "kWh"
                },
                dateTime: "2019-08-24T18:21:01.000Z"
            }
        ]
    }
}

我在reducer中的更新方法:

switch (action.type) {
    case 'update':
        return {
            ...state,
            info: {
                ...state.info,
                devData: state.info.devData.map(currentValue => {
                    if (currentValue.key === 1) {
                        currentValue.data = action.payload.data;
                        currentValue.dateTime = action.payload.dateTime;
                    }
                    return currentValue;
                })
            }
        };
}

我的问题:

  1. 我的更新方法复杂难看,难懂

  2. 我不确定,我是否真的以不可变方式进行此更新

  3. 我认为我的更新方法计算成本高,效率不高

我需要一种更新方法来解决上述问题。

【问题讨论】:

标签: javascript redux updates immutability reducers


【解决方案1】:

首先安装immer。

只需更新您想要的state 的一部分。

import produce from "immer"


(...)


switch (action.type) {
  case 'update':
    return produce(state, draft => {
      draft.info.devData[0].data = action.payload.data;
      draft.info.devData[0].dateTime = action.payload.dateTime;
      //This code is working ONLY with devData[0]
      //So, You SHOULD change this above code to work as dynamically.
    });

}

immer 是一种超级简单的方法来更新具有不变性的state。

我强烈推荐使用它。

【讨论】:

  • 能去掉map函数的使用吗?
【解决方案2】:
case “update”:
const index = this.state.devData.findIndex(v => v.key === 1);

return {
        ...state,
        info: {
            ...state.info,
            devData: 
             [
               return [
       ...state.info.devData.slice(0, index),
       {
          data: action.payload.data,
          dateTime: action.payload.dateTime
       },
       ...state.slice(index + 1)
    ]
             ]
        }
    };

这个想法是首先找到需要更新的元素的索引。之后使用扩展运算符创建新区域:slice 要更新的元素之前的所有内容 + 更新的元素 + 更新后的元素之后的所有内容。

ps。用我的手机写的,所以没有测试它

【讨论】:

  • 感谢您的回答。但是我觉得你的代码比我的还要复杂。
猜你喜欢
  • 2020-10-12
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2019-11-12
  • 2019-05-07
  • 2017-01-06
  • 1970-01-01
  • 2018-06-03
相关资源
最近更新 更多