首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将Immutable.js与redux一起使用?

如何将Immutable.js与redux一起使用?
EN

Stack Overflow用户
提问于 2015-08-08 19:44:26
回答 5查看 43.1K关注 0票数 51

Redux框架使用reducers来更改应用程序状态以响应操作。

关键要求是reducer不能修改现有的状态对象;它必须生成一个新的对象。

错误示例

代码语言:javascript
复制
import {
    ACTIVATE_LOCATION
} from './actions';

export let ui = (state = [], action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state.activeLocationId = action.id;
            break;
    }

    return state;
};

的好例子

代码语言:javascript
复制
import {
    ACTIVATE_LOCATION
} from './actions';

export let ui = (state = [], action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = Object.assign({}, state, {
                activeLocationId: action.id
            });
            break;
    }

    return state;
};

这是Immutable.js的一个很好的用例。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-08-09 08:25:45

以不可变的例子为例

代码语言:javascript
复制
import {
    ACTIVATE_LOCATION
} from './actions';

import { Map } from 'immutable';

const initialState = Map({})

export let ui = (state = initialState, action) => {
  switch (action.type) {
    case ACTIVATE_LOCATION:
      return state.set('activeLocationId', action.id);
    default:
      return state;
  }
};
票数 48
EN

Stack Overflow用户

发布于 2015-08-08 19:44:26

Immutable.js应根据需要在每个减速器中使用,例如

代码语言:javascript
复制
import {
    ACTIVATE_LOCATION
} from './actions';

import Immutable from 'immutable';

export let ui = (state, action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = Immutable
                .fromJS(state)
                .set('activeLocationId', action.id)
                .toJS();
            break;
    }

    return state;
};

然而,在这个示例中有很多开销:每次调用reducer操作时,它都必须将JavaScript对象转换为不可变对象的实例,将结果对象突变并将其转换回JavaScript对象。

一种更好的方法是将初始状态设置为不可变的实例:

代码语言:javascript
复制
import {
    ACTIVATE_LOCATION
} from './actions';

import Immutable from 'immutable';

let initialState = Immutable.Map([]);

export let ui = (state = initialState, action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = state.set('activeLocationId', action.id);
            break;
    }

    return state;
};

这样,您只需要将初始状态转换为Immutable ounce的实例。然后,每个reducer都会将其视为Immutable的实例,并将其作为Immutable的实例向下传递。问题是,在将值传递给视图上下文之前,您现在需要将整个状态强制转换为JavaScript。

如果您要在reducer中执行多个状态突变,则可能需要考虑使用.withMutations进行batching mutations

为了简单起见,我开发了一个redux-immutable库。它提供了与redux包中的同名函数等效的combineReducers函数,只是它希望初始状态和所有的reducers都能与Immutable.js对象一起工作。

票数 25
EN

Stack Overflow用户

发布于 2015-08-09 01:25:03

如果你只是在寻找一种简单的方法来进行更新而不会发生变化,我维护了一个库:https://github.com/substantial/updeep,在我看来,这是使用redux实现这一点的一个好方法。

updeep允许您使用常规(冻结)对象层次结构,因此您可以进行解构,查看日志和调试器中的对象等。对于大型数据集,它不会像Immutable.js那样高效,因为如果需要,它确实会克隆对象。

下面是一个示例(但请查看自述文件中的更多内容):

代码语言:javascript
复制
import {
    ACTIVATE_LOCATION
} from './actions';
import u from 'updeep';

export let ui = (state = [], action) => {
    switch (action.type) {
        case ACTIVATE_LOCATION:
            state = u({ activeLocation: action.id }, state);
            break;
    }

    return state;
};
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31892767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档