当我们的应用随着业务的发展,变得越来越复杂的时候,组件之间的状态也是越来越复杂。
reducer函数
之前说过redux中的action,是用来描述一种变化。但是完成变化并且生辰新的数据数据状态的是reducer方法。
reducer方法,必须是纯函数,才能保证数据变化的可预测性。也就是说执行每一步变化,我们都可以预测数据的结果。比如:
export default function menuReducer(
state = {
menuState,
isCollapse: false,
},
action: any
) {
switch (action.type) {
case types.MENU_COLLAPSES:
return {
...state,
isCollapse: action.payload,
};
default:
return { ...state };
}
}
这reducer函数,是控制菜单的收缩状态的,它对应的action,我是这样写的:
import * as types from "@/store/types";
export const changeCollapse = (isCollapse: boolean) =>({
type: types.MENU_COLLAPSES,
payload: isCollapse,
});
按钮组件的代码如下:
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
import { connect } from "react-redux";
import { changeCollapse } from "@/store/redux/menu/action";
const CollapsesIcon = (props: any) => {
const { isCollapses, changeCollapse } = props;
return (
<div
className="collapsed"
onClick={() => {
changeCollapse(!isCollapses)
}}
>
{isCollapses ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
</div>
);
};
const mapStateToProps = (state: any) => {
return { isCollapses: state.menus.isCollapse };
};
const mapDispatchToProps = { changeCollapse };
export default connect(mapStateToProps, mapDispatchToProps)(CollapsesIcon);
在一个应用中,我们不可能使用一个action来描述所有的变化,这样不利于维护。一般情况是一个action描述一种变化,同时也会定义对应的reducer函数。
redux提供了一个工具函数combineReducers,来合并所有的reducer函数。比如:
import { combineReducers } from "redux";
import menuReducer from "../redux/menu/menu";
import globalReducer from "../redux/global/reducer";
import { auth } from "../redux/auth";
const reducers = combineReducers({
menus: menuReducer,
global:globalReducer,
auth
});
export default reducers
combineReducers函数接收一个Object类型的参数,这个参数包含了页面的数据状态、已经状态数据和reducer函数之间的映射关系。
这就是redux的纯函数reducer。
中间件
redux中间件就是在派发action和执行reducer之间,添加一些自定义的功能。
比如记录日志、调用异步接口或者路由等等。
redux是通过applyMiddleware方法来接入中间件的,比如:
let store = legacy_createStore(configStore, composeEnhancers(
applyMiddleware(...middleware, reduxPromise)
));
比如现在在开发环境中,想记录一下状态数据变化的日志,可以使用redux-logger:
import { createLogger } from 'redux-logger';
const logger = createLogger();
store = legacy_createStore(configStore, composeEnhancers(
applyMiddleware(...middleware, reduxPromise,logger)
));
这样就是轻松的查看状态数据的变化记录。
但是,需要留意一下,redux-logger需要放在所有中间件的最后面,才能准确打印日志哦。