我可以使用setIn在空数组上创建新索引吗?

时间:2017-10-27 17:03:16

标签: javascript reactjs

我的问题是,在这个结构中使用inmutable:

myMap = Map({a: [], b: []});
myMAp.setIn(['a', 0], 'v');

这是一个异常

immutable.js:870 Uncaught (in promise) Error: invalid keyPath
    at invariant (immutable.js:870)
    at updateInDeepMap (immutable.js:1974)
    at updateInDeepMap (immutable.js:1980)
    at Map.updateIn (immutable.js:1278)
    at Map.setIn (immutable.js:1256)

我知道我可以检查是否存在这样的索引,如果没有则初始化,然后尝试更新,但是可能一个功能请求是可行的,所以不能让我们一步到位。我没有看到任何无法在这个用例上引发异常的动机。 我正在阅读http://untangled.io/immutable-js-all-the-examples-youll-ever-need-to-get-set-and-delete-data-from-lists/上的图书馆规范 我建议的是列表中的正常内容:

  

如果keyPath中的任何地方都不存在索引,那么List.setin()   将执行以下操作之一:

     

如果坏索引之前的索引引用了List,那么坏   index正试图在一个边界之外的地方插入一个值   这个清单。通常的规则适用,并且List扩展,值为   放置在展开的List的末尾,并插入空值   之间。通过替换以下示例,在下面的示例中尝试自己   最后一行有avengersList.setIn([1,1,1,3],'scarletWitch');如果   坏索引之前的索引是一个值(即不是List或Map),   然后坏索引试图将值插入到数据类型中   没有指数的概念;因此,将出现无效的keyPath错误   被抛出通过替换以下示例,在下面的示例中尝试自己   最后一行有avengersList.setIn([0,1],'scarletWitch');.这试试   将'scarletWitch'插入字符串'ironMan',这绝不是   去上班了!

2 个答案:

答案 0 :(得分:1)

你的问题没有意义,因为你说你想在List中创建一个新索引,但是你试图访问一个不存在的[0](它是一个空数组,所以它还没有keyPath索引),但是对象属性确实存在,保存了这个updateIn,所以这就是你想要使用的,你想要{{ 1}}而不是setIn。这就是我认为的样子:

//a doesn't have to be an `Immutable.List`, it can be a plain JS array
var myMap = Immutable.Map({a: Immutable.List([]), b: []}) 
var Rogelio = myMap.updateIn(['a'], list => list.push(0))
console.log(Rogelio)

答案 1 :(得分:0)

第一个错误的假设:Map构造函数从对象和数组进行深度转换为MapsLists。您需要fromJS功能。

    //const { fromJS, Map, List } = require('immutable');
    myMap = fromJS({a: [], b: []});
    var myMap2 = myMap.setIn(['a', 0], 'v');
    console.log(myMap2);

第二个错误的错误。考虑setIn对 inmutable myMap做一些更改。如果您想要对更改的结构执行某些操作(保存为新状态),则setIn的克隆结果必须转到新变量。