【问题标题】:Immutable.js setIn not workingImmutable.js setIn 不起作用
【发布时间】:2017-11-03 14:29:13
【问题描述】:

我有以下列表,我试图从中返回一个新列表,但我不断收到如下所示的错误。有什么想法吗?

export const questions = List([
  {uuid: uuid(), order: 0, text: 'Which country do you live in?', choices: [
    { choice: 'United States', added: true },
    { choice: 'Canada', added: true },
    { choice: 'Australia', added: true }
  ]},
  {uuid: uuid(), order: 1, text: 'Which country were you born in?', choices: [
    { choice: 'Mexico', added: true },
    { choice: 'California', added: true },
    { choice: 'Seoul', added: true }
  ]}
]);


questions.setIn([0, 'text'], 'changed') 

导致此错误:

immutable.js:870 Uncaught Error: invalid keyPath
    at invariant (immutable.js:870)
    at updateInDeepMap (immutable.js:1974)
    at updateInDeepMap (immutable.js:1980)
    at List.Map.updateIn (immutable.js:1278)
    at List.Map.setIn (immutable.js:1256)
    at eval (eval at ./src/reducers/questionsList.js (questionsList.js:17), <anonymous>:1:11)

【问题讨论】:

标签: javascript redux immutable.js


【解决方案1】:

在 Immutable 4.0.0-rc9 中,这实际上应该满足您的需求。在 3.x 中,setIn 仅适用于深度不可变列表,但根据最新文档:

纯 JavaScript 对象或数组可以嵌套在 Immutable.js 集合中,setIn() 也可以更新这些值,通过创建应用更改的这些值的新副本来不可变地处理它们。


this answer

问题在于questions 是一个原始 JS 对象的不可变列表。 List#setIn() 仅适用于深度不可变的对象。您可能想要设置 questions = Immutable.fromJS(...) 来获得一个深度不可变的对象。

但是,如果 有意将原版 JS 对象放入不可变对象中(我真的希望不是这样),那么你'd 想要做的是使用 Immutable 来获取 vanilla 对象,然后使用常规 ol' 赋值来更改值:

questions.get(0)['text'] = 'changed'

【讨论】:

    【解决方案2】:

    尝试更新 immutable.js 库

    【讨论】:

      猜你喜欢
      • 2016-10-04
      • 2015-12-08
      • 2019-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 2015-08-31
      相关资源
      最近更新 更多