【问题标题】:React Redux: Using Immutable in Reduce StateReact Redux:在 Reduce 状态下使用不可变
【发布时间】:2018-06-23 12:51:23
【问题描述】:

我正在学习 Immutable.js,但我很难在 reducer 中处理 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 中,我将默认状态声明为不可变 Map() 对象:

let store = createStore(..., Map({}), composeEnhancers(...));

在 combineReducers 中,我使用的是“redux-immutable”。

import { combineReducers } from 'redux-immutable';  

用 Immutable.js 修改 reducer 状态的正确方法是什么?

【问题讨论】:

    标签: javascript reactjs redux react-redux immutable.js


    【解决方案1】:

    toJS 和 fromJS 是昂贵的操作。 您不应该使用 initial_state 或 state 的 fromJS。

    我建议你在你的 users reducer 上这样做以获得更好的性能并且不要处理 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; 
    }

    请不要在创建 Store 时使用 immutable。您不需要任何不可变的操作,因为它假定商店是不可变的。 所以 Immutable 应该是 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;
    }

    在文件 state/reducers 中,您拥有不同实体的所有 reducer:

    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;

    最好的!

    【讨论】:

      【解决方案2】:

      我假设在 reducer 中返回的 state 不是不可变映射。据我所知,您只是通过使用 fromJS(...) 将初始状态转换为不可变映射,您可以尝试在减速器中做同样的事情。

      return fromJS(state)
              .setIn(.setIn(['users', 'isLoading'], false)
              .setIn(['users', 'items'], fromJS(action.users))
      

      但我建议您查看this documentation,因为它针对您的需求。

      【讨论】:

        猜你喜欢
        • 2016-02-22
        • 2019-01-10
        • 2019-02-01
        • 1970-01-01
        • 2016-11-10
        • 1970-01-01
        • 2019-03-16
        • 2017-10-15
        • 1970-01-01
        相关资源
        最近更新 更多