我正在学习Immutable.js,但我在减速器中处理Immutable.js时遇到了困难。
我已经将我的initialState声明为:
import { fromJS } from 'immutable';
const INITIAL_STATE = fromJS({
users: {
isLoading: false,
items: []
}
});
我试图修改initialState但我收到错误:" state.setIn不是函数"。
case 'FETCH_USERS_SUCCESS':
return state
.setIn(['users', 'isLoading'], false)
.setIn(['users', 'items'], action.users)
在index.js中,我将deafult状态声明为Immutable Map()对象:
let store = createStore(..., Map({}), composeEnhancers(...));
在combineReducers中,我使用了' redux-immutable'。
import { combineReducers } from 'redux-immutable';
使用Immutable.js修改reducer状态的正确方法是什么?
答案 0 :(得分:1)
toJS和fromJS是昂贵的操作。 您不应执行initial_state或state的fromJS。
我建议您在用户减速器上执行此操作,以获得更好的性能,并且不要处理toJS和fromJS。并在代码(选择器,组件,视图)中使用get获取任何值。
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import { FETCH_USERS_SUCCESS } from './constants'; // or whatever you have your constants file
const initialState = new ImmutableMap({
isLoading: false,
items: new ImmutableList([]);
});
function users(state = initialState, action) {
switch (action.type):
case FETCH_USERS_SUCCESS:
return state.merge({
isFetching: false,
users: action.users
});
default:
return state;
}
请,在创建商店时不要使用不可变的。您不需要执行任何不可变的操作,因为它认为商店是不可变的。 因此,Reducer内部的任何数据结构都应该是不可变的。
这是一个常见的配置存储文件(在您的情况下为索引)的示例:
import { applyMiddleware, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import rootReducer from 'state/reducers';
export default function configureStore(initialState = {}) {
const store = createStore(
rootReducer,
initialState,
composeWithDevTools(applyMiddleware(thunk)),
);
// to query state in the console
window.appState = store.getState();
if (module.hot) {
const nextReducer = require('state/reducers');
module.hot.accept('state/reducers', () => {
store.replaceReducer(nextReducer);
});
}
return store;
}
在文件状态/化简器中,您具有所有不同实体的化简器:
import { combineReducers } from 'redux';
import users from './users';
const ownReducers = {};
const appReducer = combineReducers({
...ownReducers,
// add here your reducers after importing the entity state
// i.e: myStuff: myStuff.reducer, etc...
users: claims.reducer,
});
const rootReducer = (state, action) => {
return appReducer(state, action);
};
export default rootReducer;
最好!
答案 1 :(得分:0)
我假设在reducer中返回的state
不是不可变映射。据我所知,您只是使用fromJS(...)
将初始状态转换为不可变映射,您可以尝试在reducer中执行相同的操作。
return fromJS(state)
.setIn(.setIn(['users', 'isLoading'], false)
.setIn(['users', 'items'], fromJS(action.users))
但我建议您查看this documentation,因为它针对您的要求。