當咱們的系統變得愈來愈複雜的時候,使用一個Reducer函數來管理全局數據,會讓一個Reducer函數變得臃腫,不利於後期的開發和管理。react
好比一個圖書館應用系統,咱們須要管理圖書數據,圖書館管理員數據,讀者數據,借閱記錄數據採購數據等等。若是把這些數據放在一個Reducer中,那麼會形成數據管理的混亂,不利於後期的維護和開發。redux
一個比較好的解決方案是:創建多個Reducer,分別用於管理圖書,管理員,讀者等數據。當咱們須要更新圖書數據的時候,只須要查看管理圖書的Reducer代碼便可,無需關心其餘Reducer。這樣既省時省力,有能夠減小開發中的bug。markdown
下面咱們就來介紹一個若是創建多個Reducer,即如何拆分大的Reducer。數據結構
好比咱們如今要開發一個圖書館應用,須要對圖書館中的圖書和管理員進行管理。ide
圖書數據管理要求以下:查看圖書列表,向圖書列表中增長新的圖書,從圖書列表中刪除圖書。函數
管理員數據管理要求以下:設置管理員的姓名,角色等信息測試
有了這個簡單的業務場景,咱們開始設置對應的Redux設置吧。ui
首先咱們須要建立幾個action tye常量,新建UserType.js文件,代碼以下:this
export const SET_FIRST_NAME = "SET_FIRST_NAME";
export const SET_LAST_NAME = "SET_LAST_NAME";
export const ADD_NEW_USER_ROLE = "ADD_NEW_USER_ROLE";
export const REMOVE_USER_ROLE = "REMOVE_USER_ROLE";
複製代碼
建立按完成以後,使用這些常量定義action,用來調用reducer中的邏輯。新建UserAction.js文件,代碼以下:spa
import { SET_FIRST_NAME, SET_LAST_NAME, ADD_NEW_USER_ROLE, REMOVE_USER_ROLE } from "./UserType"
export const setFirstName = firstName => {
return {
type: SET_FIRST_NAME,
payload: firstName
}
}
export const setLastName = lastName => {
return {
type: SET_LAST_NAME,
payload: lastName
}
}
export const addNewUserRole = newUserRole => {
return {
type: ADD_NEW_USER_ROLE,
payload: newUserRole
}
}
export const removeUserRole = roleName => {
return {
type: REMOVE_USER_ROLE,
payload: roleName
}
}
複製代碼
最後根據定義reducer函數,用來相應action中的動做,新建UserReducer.js文件,代碼以下:
// 定義原始user數據,reducer的做用就是修改這些數據,而後返回這些數據
const initialUserState = {
firstName: "",
lastName: "",
userRoleList: []
}
// 引入type常量,reducer中收到action發送過來的數據,在reducer中判斷type類型,進行處理
import { SET_FIRST_NAME, SET_LAST_NAME, ADD_NEW_USER_ROLE, REMOVE_USER_ROLE } from "./UserType"
const UserReducer = (state = initialUserState, action) => {
switch(action.type) {
case SET_FIRST_NAME:
return {
...state,
firstName: action.payload
}
case SET_LAST_NAME:
return {
...state,
lastName: action.payload
}
case ADD_NEW_USER_ROLE:
let newUserRoleList = [...state.userRoleList]
if (!newUserRoleList.includes(action.payload)) {
newUserRoleList.push(action.payload)
}
return {
...state,
userRoleList: newUserRoleList
}
case REMOVE_USER_ROLE:
return {
...state,
userRoleList: state.userRoleList.filter(roleName => roleName !== action.payload)
}
default:
return state;
}
}
export default UserReducer;
複製代碼
同理,首先新建BookType.js文件,定義type常量。
export const ADD_NEW_BOOK = "ADD_NEW_BOOK";
export const REMOVE_NEW_BOOK = "REMOVE_NEW_BOOK";
複製代碼
而後使用這些常量定義action,新建BookAction.js文件,代碼以下:
import { ADD_NEW_BOOK, REMOVE_NEW_BOOK } from "./BookType";
export const addNewBooks = newBookName => {
return {
type: ADD_NEW_BOOK,
payload: newBookName
}
}
export const removeNewBooks = bookName => {
return {
type: REMOVE_NEW_BOOK,
payload: newBookName
}
}
複製代碼
最後定義reducer,管理圖書信息,新建BookReducer.js文件,代碼以下:
const initialBookState = {
bookList: ["明朝那些事", "水滸傳"]
}
import { ADD_NEW_BOOK, REMOVE_NEW_BOOK } from "./BookType";
const BookReducer = (state = initialBookState, action) => {
if (action.type === ADD_NEW_BOOK) {
return {
...initialBookState,
bookList: [...initialBookState.bookList, action.payload]
}
}
if (action.type === REMOVE_NEW_BOOK) {
return {
...initialBookState,
bookList: initialBookState.bookList.filter(_book => _book !== action.payload)
}
}
return state;
}
export default BookReducer;
複製代碼
如今咱們已經建立了兩個reducer,下面須要作的就是把這兩個reducer合併起來,建立一個redux store實例。這裏須要用到 redux 包提供的combineReducers方法,新建Store.js文件,具體代碼以下:
// 引入須要的redux方法
import { createStore, combineReducers } from 'redux'
// 引入定義好的reducer
import BookReducer from './BookReducer'
import UserReducer from './UserReducer';
// 使用該方法合併兩個reducer
const rootReducer = combineReducers({
BookReducer,
UserReducer
});
// 使用合併後的reducer建立store實例
const Store = createStore(rootReducer)
export default Store;
複製代碼
如今咱們已經建立了reduxe實例,能夠在一個組件中獲取redux中的數據,看下此時的數據結構是怎樣的,組件代碼以下:
import React from 'react'
import Store from 'myRedux/Store'
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
this.setState((preState, props) => ({
...preState,
...Store.getState()
}));
Store.subscribe(() => {
// 打印出redux中的數據
console.log("Redux data: ", Store.getState());
this.setState((preState, props) => ({
...preState,
...Store.getState()
}));
});
}
render() {
return (
<div> 測試頁面 </div>
);
}
}
export default Login;
複製代碼
在控制檯中,咱們能夠看到redux中的數據結構以下:
{
"UserReducer": {
"firstName": "",
"lastName": "",
"userRoleList": []
},
"BookReducer": {
"bookList": [
"明朝那些事",
"水滸傳"
]
}
}
複製代碼
瞭解redux的數據結構,在後期獲取這些數據的時候,咱們就不會出錯了。
如今數據有了,咱們還要可以修改多個reducer的數據,其實很是簡單。雖然咱們定義了兩個reducer,可是徹底看做是一個reducer,在修改數據的時候遵循這樣的流程:引入action,而後觸發action。好比下面的代碼實例:
import React from 'react';
import Store from "myRedux/Store";
// 引入action
import { setFirstName, setLastName } from "myRedux/UserAction";
const LeftSideBar = () => {
const modifyUserName = () => {
// 觸發action
Store.dispatch(setFirstName("Allen"));
Store.dispatch(setLastName("Feng"));
}
return (
<div> <button className="icon" onClick={modifyUserName} ></button> </div>
);
}
export default LeftSideBar;
複製代碼
如何建立多個reducer來管理redux數據,個人心得就是上述這些。在一些很大的項目中,建立多個reduxer能夠幫助咱們清晰明瞭的管理redux中的數據,這一點但願你們能夠嘗試一下。