Redux:从combineReducers和"松散"创建根减速器。性能

时间:2016-09-01 00:44:39

标签: javascript reactjs redux

我想创建一个具有以下形状的Redux商店:

store = {
  loaded: Boolean,
  loading: Boolean,
  view: Object, // uses combineReducers
  layers: Object // uses combineReducers
}

到目前为止,我的root reducer看起来像这样:

rootReducer.js

import view from './view';
import layers from './layers';

const initialState = {
  loaded: false,
  loading: false,
};

function loadState(state = initialState, action = {}) {
  switch (action.type) {
    case 'LOADED':
      return {
        ...state,
        loaded: true,
        loading: false,
      };

    case 'LOADING':
      return {
        ...state,
        loaded: false,
        loading: true,
      };

    default:
      return state;
  }
}

export default combineReducers({
  view,
  layers,
  // hmmmm, putting loadState here would give me a loadState object property,
  // not loose 'loaded' and 'loading' properties
});

我如何将这些"松散"像loadedloading这样的属性?

2 个答案:

答案 0 :(得分:7)

@PhiNguyen是对的,我需要将这些加载/加载属性转换为自己的reducer!

import { LOADED, LOADING } from '../ActionTypes';

export function loaded(state = false, action = {}) {
  switch (action.type) {
    case LOADED:
      return true;

    case LOADING:
      return false;

    default:
      return state;
  }
}

export function loading(state = false, action = {}) {
  switch (action.type) {
    case LOADED:
      return false;

    case LOADING:
      return true;

    default:
      return state;
  }
}

<强> rootReducer.js

import { loaded, loading } from './load';
import view from './view';
import layers from './layers';

export default combineReducers({
  loaded,
  loading,
  view,
  layers
});

答案 1 :(得分:5)

有时候我发现为一些简单的属性编写单独的reducer是令人讨厌的开销,所以我有时会使用combineReducersWithRoot实用程序。

export function combineReducersWithRoot(rootReducer, reducers) {
  return (state, action) => {
    // Ensure the root state object is a new object; otherwise
    // React may not re-render.
    let newState = {...rootReducer(state, action)};
    Object.keys(reducers).forEach(domain => {
      let obj = state ? state[domain] : undefined;
      newState[domain] = reducers[domain](obj, action);
    });
    return newState;
  };
}

现在,给定一个像这样的状态结构:

{
  loading: bool
  loaded: bool
  data: {
    filter: string
    arr: object[]
  }
}

你可以这样做:

function rootReducer(state = {loading: false, loaded: false}, action) {
  switch(action.type) {
    case STARTED_LOADING:
      return {...state, loading: true, loaded: false};
    case FINISHED_LOADING:
      return {...state, loading: false, loaded: true};
    default:
      return state;
  }
}

function dataReducer(state = {filter: '', arr: []}, action) {
  switch (action.type) {
    case SET_FILTER:
      return {...state, filter: action.value};
    case SET_DATA:
      return {...state, arr: action.arr};
    default:
      return state;
  }
}

export default combineReducersWithRoot(rootReducer, {data: dataReducer});