Redux - Reducer
Reducer 是 Redux 中的纯函数。纯函数是可预测的。Reducer 是改变 Redux 中状态的唯一方式。它是唯一可以编写逻辑和计算的地方。Reducer 函数将接收应用程序的先前状态和正在分发的 action,计算下一个状态并返回新的对象。
以下几件事永远不应该在 reducer 中执行:
- 更改函数参数
- API 调用和路由逻辑
- 调用非纯函数,例如 Math.random()
以下是 reducer 的语法:
(state,action) => newState
让我们继续在 action 创建者模块中讨论的网页上显示产品项目列表的示例。让我们看看下面如何编写它的 reducer。
const initialState = {
isLoading: false,
items: []
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'ITEMS_REQUEST':
return Object.assign({}, state, {
isLoading: action.payload.isLoading
})
case ‘ITEMS_REQUEST_SUCCESS':
return Object.assign({}, state, {
items: state.items.concat(action.items),
isLoading: action.isLoading
})
default:
return state;
}
}
export default reducer;
首先,如果您没有将 state 设置为“initialState”,Redux 将使用未定义的 state 调用 reducer。在这个代码示例中,JavaScript 的 concat() 函数用于“ITEMS_REQUEST_SUCCESS”,它不会更改现有数组;而是返回一个新数组。
这样,您可以避免更改状态。永远不要直接写入状态。“ITEMS_REQUEST”中,我们必须根据接收到的 action 设置 state 值。
前面已经讨论过,我们可以在 reducer 中编写我们的逻辑,并可以根据逻辑数据进行拆分。让我们看看在处理大型应用程序时如何拆分 reducer 并将它们组合在一起作为根 reducer。
假设,我们想设计一个网页,用户可以在其中访问产品订单状态并查看愿望清单信息。我们可以将逻辑分离到不同的 reducer 文件中,并使它们独立工作。让我们假设 GET_ORDER_STATUS action 被分发以获取与某个订单 ID 和用户 ID 对应的订单状态。
/reducer/orderStatusReducer.js
import { GET_ORDER_STATUS } from ‘../constants/appConstant’;
export default function (state = {} , action) {
switch(action.type) {
case GET_ORDER_STATUS:
return { ...state, orderStatusData: action.payload.orderStatus };
default:
return state;
}
}
类似地,假设 GET_WISHLIST_ITEMS action 被分发以获取用户的愿望清单信息。
/reducer/getWishlistDataReducer.js
import { GET_WISHLIST_ITEMS } from ‘../constants/appConstant’;
export default function (state = {}, action) {
switch(action.type) {
case GET_WISHLIST_ITEMS:
return { ...state, wishlistData: action.payload.wishlistData };
default:
return state;
}
}
现在,我们可以使用 Redux combineReducers 实用程序组合这两个 reducer。combineReducers 生成一个函数,该函数返回一个对象,其值是不同的 reducer 函数。您可以将所有 reducer 导入 index reducer 文件,并将它们组合在一起作为一个对象,并带有各自的名称。
/reducer/index.js
import { combineReducers } from ‘redux’;
import OrderStatusReducer from ‘./orderStatusReducer’;
import GetWishlistDataReducer from ‘./getWishlistDataReducer’;
const rootReducer = combineReducers ({
orderStatusReducer: OrderStatusReducer,
getWishlistDataReducer: GetWishlistDataReducer
});
export default rootReducer;
现在,您可以将此 rootReducer 传递给 createStore 方法,如下所示:
const store = createStore(rootReducer);