Reducer是用于改变数据的函数
1.一个数据仓库,有且仅有一个reducer,并且通常情况下,一个工程只有一个仓库,因此,一个系统,只有一个reducer
2.为了方便管理,通常会将reducer放到单独的文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import * as actionTypes from './action/action-type';
export default function reducer(state, action) { if (action.type === actionTypes.INCREASE) { return state + 1; } else if (action.type === actionTypes.DECREASE) { return state - 1; } else if (action.type === actionTypes.SET) { return action.payload; } else { return state; } }
|
1 2 3 4 5 6
| import { createStore, bindActionCreators } from 'redux'; import * as numberActions from './action/number-action'; import reducer from './reducer';
const store = createStore(reducer, 10);
|
3.reducer被调用的时机
①.通过store.dispatch,分发了一个action,此时,会调用reducer
②.当创建一个store的时候,会调用一次reducer,主要是为了初始化
- 可以利用这一点,用reducer初始化状态
- 创建仓库时,不传递任何默认状态
- 将reducer的参数state设置一个默认值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import * as actionTypes from './action/action-type';
export default function reducer(state=10, action) { if (action.type === actionTypes.INCREASE) { return state + 1; } else if (action.type === actionTypes.DECREASE) { return state - 1; } else if (action.type === actionTypes.SET) { return action.payload; } else { return state; } }
|
1 2 3 4 5 6
| import { createStore, bindActionCreators } from 'redux'; import * as numberActions from './action/number-action'; import reducer from './reducer';
const store = createStore(reducer);
|
4.reducer内部通常使用switch来判断type值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import * as actionTypes from '../action/action-type';
export default function reducer(state = 10, action) { console.log('reducer被调用了', state, action); switch (action.type) { case actionTypes.INCREASE: return state + 1; case actionTypes.DECREASE: return state - 1; case actionTypes.SET: return action.payload; default: return state; } }
|
5.reducer必须是一个没有副作用的纯函数
为什么需要是纯函数
a.纯函数有利于测试和调试
b.有利于还原数据
c.有利于将来与react结合时的优化
具体要求
a.不能改变参数,因此若要让状态变化,必须得到一个新的状态
b.不能有异步
c.不能对外部环境造成影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import * as actionTypes from '../action/action-type';
export default function reducer(state = { name: 'jerry', age: 12 }, action) { switch (action.type) { case actionTypes.INCREASE: return { ...state, age: state.age + 1 }; case actionTypes.DECREASE: return state - 1; case actionTypes.SET: return action.payload; default: return state; } }
|
6.由于在大中型项目中,操作比较复杂,数据结构也比较复杂,因此,需要对reducer进行细分。
①.redux提供了方法,可以帮助我们更加方便的合并reducer(vscode快捷创建reducer方式:rxreducer)
1 2 3 4 5 6 7 8 9 10 11 12
| import { SET_LOGIN_USER_TYPE } from '../action/loginuser-action'; const initialState = null;
export default (state = initialState, { type, payload }) => { switch (type) { case SET_LOGIN_USER_TYPE: return payload; default: return state; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import * as usersAction from '../action/users-action'; import uuid from 'uuid'; const initialState = [ { id: uuid(), name: '用户1', age: 11 }, { id: uuid(), name: '用户2', age: 12 }, ];
export default (state = initialState, { type, payload }) => { switch (type) { case usersAction.ADD_USER: return [...state, payload]; case usersAction.DELETE_USER: return state.filter((user) => user.id !== payload.id); case usersAction.UPDATE_USER: return state.map((user) => (user.id === payload.id ? {...user, ...payload} : user)); default: return state; } };
|
1 2 3 4 5 6 7 8 9 10 11 12
| import loginUserReducer from './loginUser'; import usersReducer from './users';
export default (state = {}, action) => { const newState = { loginUser: loginUserReducer(state.loginUser, action), users: usersReducer(state.users, action), }; return newState; };
|
②.combineReducers: 合并reducer,得到一个新的reducer,该新的reducer管理一个对象,该对象中的每一个属性交给对应的reducer管理。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import loginUserReducer from './loginUser'; import usersReducer from './users'; import { combineReducers } from 'redux';
export default combineReducers({ loginUser: loginUserReducer, users: usersReducer, });
|