Redux 学习笔记04——使用多个Reducer管理数据

写在前面

当咱们的系统变得愈来愈复杂的时候,使用一个Reducer函数来管理全局数据,会让一个Reducer函数变得臃肿,不利于后期的开发和管理。react

好比一个图书馆应用系统,咱们须要管理图书数据,图书馆管理员数据,读者数据,借阅记录数据采购数据等等。若是把这些数据放在一个Reducer中,那么会形成数据管理的混乱,不利于后期的维护和开发。redux

一个比较好的解决方案是:创建多个Reducer,分别用于管理图书,管理员,读者等数据。当咱们须要更新图书数据的时候,只须要查看管理图书的Reducer代码便可,无需关心其余Reducer。这样既省时省力,有能够减小开发中的bug。markdown

下面咱们就来介绍一个若是创建多个Reducer,即如何拆分大的Reducer。数据结构

假设业务场景

好比咱们如今要开发一个图书馆应用,须要对图书馆中的图书和管理员进行管理。ide

图书数据管理要求以下:查看图书列表,向图书列表中增长新的图书,从图书列表中删除图书。函数

管理员数据管理要求以下:设置管理员的姓名,角色等信息测试

有了这个简单的业务场景,咱们开始设置对应的Redux设置吧。ui

建立第一个reducer,管理图书馆管理员的数据

首先咱们须要建立几个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;
复制代码

建立第二个reducer,管理图书的数据

同理,首先新建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 store实例

如今咱们已经建立了两个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;
复制代码

使用多个reducer建立的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,可是彻底看做是一个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中的数据,这一点但愿你们能够尝试一下。

相关文章
相关标签/搜索