Redux - Reducer
Reducer 是 Redux 中的纯函数。 纯函数是可预测的。 Reducer 是 Redux 中改变状态的唯一方法。 这是唯一可以编写逻辑和计算的地方。 Reducer 函数将接受应用程序和正在分派的操作的先前状态,计算下一个状态并返回新对象。
以下几件事绝对不应该在reducer内部执行 −
- 函数参数的突变
- API 调用和路由逻辑
- 调用非纯函数,例如 Math.random()
以下是reducer的语法 −
(state,action) => newState
让我们继续在网页上显示产品项目列表的示例,这在操作创建者模块中进行了讨论。 下面让我们看看如何编写它的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 会以未定义的状态调用reducer。 在此代码示例中,"ITEMS_REQUEST_SUCCESS"中使用了 JavaScript 的 concat() 函数,该函数不会更改现有数组; 相反,返回一个新数组。
这样就可以避免状态的突变。 切勿直接写入状态。 在"ITEMS_REQUEST"中,我们必须根据收到的操作设置状态值。
我们已经讨论过,我们可以在reducer中编写我们的逻辑,并可以在逻辑数据的基础上拆分它。 让我们看看在处理大型应用程序时如何拆分reducer并将它们组合在一起作为根reducer。
假设,我们要设计一个网页,用户可以在其中访问产品订单状态并查看愿望清单信息。 我们可以将不同reducers文件中的逻辑分开,让它们独立工作。 让我们假设调度 GET_ORDER_STATUS 操作来获取与某个订单 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 操作来获取各个用户的愿望清单信息。
/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 mixReducers 实用程序组合两个reducer。 mergeReducers 生成一个函数,该函数返回一个对象,该对象的值是不同的reducer函数。 您可以导入索引reducer文件中的所有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);