【问题标题】:Updating state of deep object value in React/Redux using immutable.js使用 immutable.js 在 React/Redux 中更新深层对象值的状态
【发布时间】:2016-11-09 15:21:56
【问题描述】:

我有这个非常嵌套的状态数组,需要按 Employee、Task 和 Week 更新 Hours 字段。我尝试了多种方法来使用 Immutable 但没有成功,有什么帮助吗?

这是我的数据示例:

[{
  "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"
      }
    }
  }]
}]

【问题讨论】:

  • 假设你在reducer中尝试这个?您需要更新哪些信息?您更新时的当前状态是什么?请显示您尝试过的代码,以便我们提供帮助:)。
  • 您还可以查看github.com/engineforce/ImmutableAssign,这是一个支持 TypeScript 类型检查的轻量级不可变助手,并允许您继续使用 POJO(普通旧 JavaScript 对象)。

标签: reactjs redux immutable.js


【解决方案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"
      }
    }
  }]
}]);

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

您可以使用不可变映射来迭代并找到您要查找的项目,如下所示:

  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 对象和不可变获取来检查找到正确的节点,然后一旦我处于正确的级别,我就使用 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;
});

【讨论】:

  • 这是一个很好的开始,但不能 100% 工作。对于我的目的,这是一个更现实的调整:fiddle.jshell.net/qxbq1nq3 注意输出中的第二个员工对象未定义,此外第一个员工对象缺少像“OtherData”字段这样的数据。
  • @SirM 为您更新了它。请在以后在您提出的问题中提供您的数据、代码和要求,而不仅仅是一张图片。
猜你喜欢
  • 2016-10-25
  • 2019-02-26
  • 2018-03-20
  • 1970-01-01
  • 2017-09-19
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多