如何使用ImmutableJS在Reducer中设置复杂/嵌套状态属性?
解决ImmutableJS嵌套状态更新的问题
嘿,我来帮你搞定这个嵌套属性更新的问题!因为ImmutableJS的核心是不可变性——你不能直接修改原状态对象的任何属性,哪怕是嵌套层级的,所有更新都要返回全新的Immutable对象。针对你的INBOX_INCREMENT分支,这里有几种清晰的实现方式:
方式1:分步更新(最直观)
把嵌套层级的更新拆成几步,逻辑一目了然:
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: // 1. 先取出当前的messages Immutable Map const currentMessages = state.get('messages'); // 2. 更新messages里的inbox值,返回新的messages Map const updatedMessages = currentMessages.set('inbox', currentMessages.get('inbox') + 1); // 3. 把更新后的messages放回原状态,返回全新的state return state.set('messages', updatedMessages); // 其他case和default... } }
方式2:链式调用(更简洁)
把分步操作合并成链式调用,代码更紧凑:
case INBOX_INCREMENT: return state.set( 'messages', state.get('messages').set('inbox', state.get('messages').get('inbox') + 1) );
方式3:用update方法(最优雅)
ImmutableJS的update方法专门用来基于当前值计算新值,嵌套场景下用它会更简洁:
case INBOX_INCREMENT: return state.update('messages', (messages) => messages.update('inbox', (currentCount) => currentCount + 1) );
update会自动帮你获取目标属性的当前值,你只需要在回调里返回新值就行,省去了重复调用get的麻烦。
重要提醒
确保你的初始状态是用Immutable.fromJS()转换的,这样嵌套的messages才会是Immutable Map(而不是普通JS对象),否则你调用set或update时会报错:
// 正确的初始状态创建方式 const initialState = Immutable.fromJS({ counter: 0, messages: { newMessages: 25, inbox: 100 } });
内容的提问来源于stack exchange,提问作者xcode
相关产品推荐
相关产品推荐

