使用immutable.js更新React / Redux中的深层对象值的状态

时间:2016-11-09 15:21:57

标签: reactjs redux immutable.js

我有这个非常深度嵌套的状态数组,需要通过Employee,Task和Week更新Hours字段。我试过很多方法用Immutable做这个但没有成功,有什么帮助吗?

state

以下是我的数据示例:

[{
  "Employee": "John Doe",
  "Other Data": "test",
  "Tasks": [{
    "AccessType": "Confidential",
    "DueDate": "2016-02-26 23:59:59",
    "taskId": "3",
    "TaskTitle": "testTitle",
    "Weeks": {
      "2016-10-10": {
        "Hours": "3"
      }
    }
  }]
}, {
  "Employee": "Bill Der",
  "Other Data": "test",
  "Tasks": [{
    "AccessType": "Confidential",
    "DueDate": "2016-02-26 23:59:59",
    "taskId": "3",
    "TaskTitle": "testTitle",
    "Weeks": {
      "2016-10-10": {
        "Hours": "3"
      }
    }
  }]
}]

1 个答案:

答案 0 :(得分:1)

你错过了一大堆信息让我为你完全回答这个问题,但我可以告诉你我将如何做这样的事情。

您可以利用不可变js为您提供的所有功能。因此,假设您有一个对象,其中包含变更不可变对象所需的信息,如下所示:

var changeHours = {
  "Employee": "John Doe",
  "TaskTitle": "testTitle",
  "Week": '2016-10-10',
  "Hours": "5"
}

我们有一个基本状态,就像你在那里设置的那样:

 var myState = Immutable.fromJS([{
  "Employee": "John Doe",
  "Tasks": [{
    "AccessType": "Confidential",
    "DueDate": "2016-02-26 23:59:59",
    "taskId": "3",
    "TaskTitle": "testTitle",
    "Weeks": {
      "2016-10-10": {
        "Hours": "3"
      }
    }
  }]
}]);

注意:我没有添加更多的数组,但我们将映射它们以便将它们考虑在内。

您可以使用immutables map迭代并找到您要查找的项目,如下所示:

  var newstate = myState.map((k, v) => {
  if (k.get('Employee') === changeHours.Employee) {
    return k.get('Tasks').map((k, v) => {
      if (k.get('TaskTitle') === changeHours.TaskTitle) {
                return k.setIn(['Weeks', changeHours.Week, 'Hours'], changeHours.Hours);
      }
      return k;
    })
    return k;
  }
 return k;
});

要查看它的实际效果 - http://fiddle.jshell.net/djj6u8xL/63/。我正在使用map迭代每个数组级别,并通过基于我们的changeHours对象和immutables获取来查找正确的节点,然后一旦我处于正确的级别,我只使用setIn。您也可以使用updateIn,它只取决于您的场景。

将来,请提供您的问题的所有信息,而不仅仅是数据的图片,它将更容易帮助您:)(而不必手动输入数据结构)。

修改:根据评论更新 - http://fiddle.jshell.net/qxbq1nq3/9/

代码:

  function newTasks(k) {
  return k.get('Tasks').map((k, v) => {
    if (k.get('TaskTitle') === changeHours.TaskTitle) {
      return k.setIn(['Weeks', changeHours.Week, 'Hours'], changeHours.Hours);
    }
    return k;
  });
}

var newstate = myState.map((k, v) => {
  if (k.get('Employee') === changeHours.Employee) {
    return k.set('Tasks', newTasks(k));
  }
  return k;
});