目前我有以下对象结构定义为STORE的初始状态
{
counter: 0,
messages: {
newMessages: 25,
inbox: 100
}
}
在这里,我使用的是不可变的JS,在我的化简器中,如果我想修改状态,我将实现如下:
function myReducer(state: Map<string, any>, action): Map<string, any> {
switch (action.type) {
case COUNTER_INCREMENT:
return state.set('counter', state.get('counter') + 1);
case INBOX_INCREMENT:
return state.set(xxxx, yyyy + 1);
}
return state;
}
当修改像counter
这样的简单属性时,我们可以只使用简单
state.set('counter', state.get('counter') + 1)
但是,如果我们想修改像messages.inbox
这样的复杂/嵌套属性怎么办? xxxx
和yyyy
值应该是什么?
Immutable 提供了一个setIn
命令,您可以通过该命令提供嵌套路径和设置该路径的值。
从不可变文档:
const { fromJS } = require('immutable')
const nested = fromJS({ a: { b: { c: [ 3, 4, 5 ] } } })
const nested2 = nested.mergeDeep({ a: { b: { d: 6 } } })
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }
console.log(nested2.getIn([ 'a', 'b', 'd' ])) // 6
const nested3 = nested2.updateIn([ 'a', 'b', 'd' ], value => value + 1)
console.log(nested3);
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }
const nested4 = nested3.updateIn([ 'a', 'b', 'c' ], list => list.push(6))
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }
没有直接为setIn
提供示例,但我想语义是相似的。可以在此处找到它的文档。
如果要为 messages.inbox
设置一个新值,可以使用setIn
:
return state.setIn(['messages', 'inbox'], 101)
如果要根据messages.inbox
的当前值为其设置新值,可以使用updateIn
:
return state.updateIn(['messages', 'inbox'], inbox => inbox + 1