Redux 状态管理之神器 ——combineReducers

随着前端技术的不断发展,状态管理成为了不可避免的问题。而 Redux 作为一个强大的状态管理库,已经成为了前端开发者的常用工具。在 Redux 中,combineReducers 方法则是状态管理之中的神器。

什么是 combineReducers

combineReducers 是 Redux 提供的一个函数,它用于把多个 reducer 合并成一个大的 reducer。如下所示:

import { combineReducers } from 'redux';

const rootReducer = combineReducers({
  reducer1,
  reducer2,
  ...
});

在 Redux 应用中,每一个 reducer 只能处理一个子状态,也就是说如果应用状态包含多个部分,就需要多个 reducer 来管理。

这样既增加了 reducer 的数量,也增加了代码的维护难度。combineReducers 便解决了这个问题:它接收一个对象作为参数,每个属性都代表一个 reducer,它的值为相应 reducer 函数。当应用状态更新时,每个 reducer 只负责管理自己的子状态,最后 combineReducer 会将所有 reducer 返回的子状态组合成一个大的状态树。

combineReducers 的使用

示例 1:计数器

在 Redux 应用中,最简单的例子就是一个计数器应用。我们可以运用 combineReducers 来管理计数器应用的状态:

import { createStore, combineReducers } from 'redux';

// 构造计数器 reducer
function counterReducer(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT': {
      return state + 1;
    }
    case 'DECREMENT': {
      return state - 1;
    }
    default: {
      return state;
    }
  }
}

// 合并 reducer
const rootReducer = combineReducers({
  count: counterReducer,
});

// 创建 store
const store = createStore(rootReducer);

// 输出 store 初始化后的状态
console.log(store.getState());  // { count: 0 }

// dispatch action 更新状态
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'DECREMENT' });

// 输出更新后的状态
console.log(store.getState());  // { count: 1 }

在上面的例子中,我们首先构造了计数器 reducer,然后使用 combineReducers 方法将其合并为一个大的 reducer,最后使用 createStore 方法创建了 Redux store。

接着,我们 dispatch 了三个 action 更新了状态,最后输出了更新后的状态,可以看到计数器状态已经成功更新。

示例 2:购物车

接下来我们看一个稍微复杂一点的例子:购物车应用。假设我们需要记录用户购物车中的商品数量和总价:

import { createStore, combineReducers } from 'redux';

// 构造商品 reducer
function productsReducer(state = [], action) {
  // ...
}

// 构造商品列表 reducer
function cartReducer(state = { items: [], total: 0 }, action) {
  switch (action.type) {
    case 'ADD_ITEM': {
      const newItems = state.items.concat(action.payload);
      const newTotal = state.total + action.payload.price;
      return { items: newItems, total: newTotal };
    }
    case 'REMOVE_ITEM': {
      const newItems = state.items.filter(item => item.id !== action.payload.id);
      const newTotal = state.total - action.payload.price;
      return { items: newItems, total: newTotal };
    }
    default: {
      return state;
    }
  }
}

// 合并 reducer
const rootReducer = combineReducers({
  products: productsReducer,
  cart: cartReducer,
});

// 创建 store
const store = createStore(rootReducer);

// 输出 store 初始化后的状态
console.log(store.getState());
// { products: [], cart: { items: [], total: 0 } }

// dispatch action 更新状态
store.dispatch({
  type: 'ADD_ITEM',
  payload: {
    id: 1,
    title: 'iMac Pro',
    price: 14999,
  }
});
store.dispatch({
  type: 'ADD_ITEM',
  payload: {
    id: 2,
    title: 'Macbook Pro',
    price: 9999,
  }
});
store.dispatch({
  type: 'REMOVE_ITEM',
  payload: {
    id: 1,
    title: 'iMac Pro',
    price: 14999,
  }
});

// 输出更新后的状态
console.log(store.getState());
// { products: [], cart: { items: [{ id: 2, title: 'Macbook Pro', price: 9999 }], total: 9999 } }

在上面的例子中,我们构造了两个 reducer:商品 reducer 和购物车 reducer。接着使用 combineReducers 方法将它们合并为一个大的 reducer。

注意,在购物车 reducer 中,我们返回的是一个对象,该对象包含了购物车中的商品列表和总价。这是因为在 Redux 应用中,状态是不可变的。所以在购物车 reducer 中,我们不能直接修改原有的商品列表和总价。相反,我们应该每次都返回一个新对象,该对象包含了更新后的商品列表和总价。

最后我们 dispatch 了三个 action,更新了购物车的状态,并输出了更新后的状态。可以看到购物车状态已经成功更新,并能正确地记录购物车中的商品和总价。

总结

combintReducers 方法可以让我们更好地管理 Redux 应用中的状态,它简化了状态管理的代码逻辑,减少了代码量,提高了代码可维护性。在工作中可以根据实际需要灵活运用 combineReducers 方法,提高开发效率,降低开发成本。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ad710badd4f0e0ff6f9741