Gaj*_*jus 50 javascript immutable.js redux
Redux框架使用reducers来更改应用程序状态以响应操作.
关键要求是reducer不能修改现有的状态对象; 它必须产生一个新的对象.
不好的例子:
import {
ACTIVATE_LOCATION
} from './actions';
export let ui = (state = [], action) => {
switch (action.type) {
case ACTIVATE_LOCATION:
state.activeLocationId = action.id;
break;
}
return state;
};
Run Code Online (Sandbox Code Playgroud)
好例子:
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;
};
Run Code Online (Sandbox Code Playgroud)
这是Immutable.js的一个很好的用例.
Geo*_*lah 48
以Immutable为例
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;
}
};
Run Code Online (Sandbox Code Playgroud)
Gaj*_*jus 25
Immutable.js应该根据需要在每个reducer中使用,例如
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;
};
Run Code Online (Sandbox Code Playgroud)
但是,在这个例子中有很多开销:每次调用reducer动作时,它都必须将JavaScript对象转换为Immutable实例,改变生成的对象并将其转换回JavaScript对象.
更好的方法是让初始状态为Immutable的一个实例:
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;
};
Run Code Online (Sandbox Code Playgroud)
这样,您只需要将初始状态转换为Immutable盎司的实例.然后每个reducer将它视为一个实例,Immutable并作为一个实例传递给它Immutable.问题是,现在您需要在将值传递给视图上下文之前将整个状态转换为JavaScript.
如果您在reducer中执行多个状态突变,您可能需要考虑使用批处理突变.withMutations.
为了简化操作,我开发了一个redux-immutable库.它提供的combineReducers函数等同于redux包中同名函数的功能,除了它期望初始状态和所有reducers与Immutable.js对象一起使用.
如果您只是在寻找一种简单的方法来进行无变异的更新,我会维护一个库:https://github.com/substantial/updeep,在我看来,这是一个很好的方法redux.
updeep允许您使用常规(冻结)对象层次结构,因此您可以进行解构,查看日志中的对象和调试器等.它还具有允许批量更新的强大API.对于大型数据集,它不会像Immutable.js那样高效,因为它确实需要克隆对象.
这是一个例子(但请查看README中的更多内容):
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;
};
Run Code Online (Sandbox Code Playgroud)
小智 5
接受的答案不应该是公认的答案.您需要使用immutable初始化状态,然后(如前所述)使用redux-immutablejs
const initialState = Immutable.fromJS({}) // or Immutable.Map({})
const store = _createStore(reducers, initialState, compose(
applyMiddleware(...middleware),
window.devToolsExtension ? window.devToolsExtension() : f => f
));
Run Code Online (Sandbox Code Playgroud)
比使用redux-immutablejs的combineReducers
额外提示:使用react-router-redux可以很好地工作,所以如果你想添加它,那么用react-router-redux替换reducer:
import Immutable from 'immutable';
import {
UPDATE_LOCATION
} from 'react-router-redux';
let initialState;
initialState = Immutable.fromJS({
location: undefined
});
export default (state = initialState, action) => {
if (action.type === UPDATE_LOCATION) {
return state.merge({
location: action.payload
});
}
return state;
};
Run Code Online (Sandbox Code Playgroud)
只需将其导入根减速器即可
这在redux-immutablejs的文档中也有说明
| 归档时间: |
|
| 查看次数: |
42398 次 |
| 最近记录: |