• Redux状态管理



    一、初识Redux

    Redux 是 JavaScript 状态容器(是JS库,并不是react的插件库,只不过是经常与react搭配开发,redux同样适用与vue、angular等框架搭配开发),提供可预测化的状态管理,集中式管理多组件共享状态。学过vue的同学,应该接触过vuex,redux就相当于vuex。

    二、使用步骤

    1.安装

    安装稳定版:

    npm install --save redux
    
    • 1

    2.三大原则

    Redux 可以用这三个基本原则来描述:

    • state以单一对象存储在store对象中
    • state只读(每次都返回一个新的对象)
    • 适用reducer执行state更新

    3.reducer工作流

    在这里插入图片描述

    4.核心步骤

    在src文件夹下创建store文件夹,并分别创建index.js和reducer.js文件。

    store

    在index文件中创建store,创建store的时候需要传入一个reducer,这是为了,每次store.dispatch发送一个新的action后,redux都会自动调用reducer,并返回新的state。

    import { createStore } from 'redux'
    const store = createStore(reducer)
    export default store
    
    • 1
    • 2
    • 3

    reducer

    在reducer文件中创建reducer,reducer就是用来计算新的store的,reducer接收两个参数:当前的state和接收到的action,它会经过计算,然后返回一个新的state。我们不能直接更改state,必须通过返回一个新的state来进行变更。
    但是在reducer第一次执行的时候,store传的state是undefined,所以准备了一个initialState作为默认值,复制给state,然后再把这个state返回给store,所以initialState实际上,就是store的初始值。

    const initialState = { num: 0 };
    const reducer = (prevState = initialState, action) => {
      let newState = {...prevState}
      switch (action.type) {
          case 'ADD':
          		newState.num = 1
                return newState;
          default:
                return prevState;
    }};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • combineReducers用法
      如果不同的action之间不存在联系,可以将reducer函数进行拆分,不同的函数负责处理不同的逻辑,最后通过combineReducers合并为大Reducer。
    // reducers.js,不同的reducer函数
    export default theDefaultReducer = (state = 0, action) => state;
    
    export const firstNamedReducer = (state = 1, action) => state;
    
    export const secondNamedReducer = (state = 2, action) => state;
    
    
    // rootReducer.js
    import {combineReducers, createStore} from "redux";
    
    import theDefaultReducer, {firstNamedReducer, secondNamedReducer} from "./reducers";
    
    // 使用 ES6 的对象字面量简写方式定义对象结构
    const rootReducer = combineReducers({
        theDefaultReducer,
        firstNamedReducer,
        secondNamedReducer
    });
    // 合并为大的rootReducer函数
    const store = createStore(rootReducer);
    console.log(store.getState());
    // {theDefaultReducer : 0, firstNamedReducer : 1, secondNamedReducer : 2}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    action

    每个 action 必须有一个 type 属性,这表示 action 的名称,然后还可以有一个 payload 属性,这个属性可以带一些参数,用作 Store 变更。

    const action = {
      type: 'ADD_ITEM',
      payload: 'theme', // 可选属性
    }
    
    • 1
    • 2
    • 3
    • 4
    • ActionTypes的拆分
      如果action的type值是自定义的字符串,那么就算字符串写错了,页面是不会报错,这很不利于我们定位问题、解决问题。所以,我们可以对action的type进行拆分,使用常量代替原来的字符串。这样的话,假如我们在使用过程中,不小心写错了变量某个字符,页面也会报错。
    // 在store下创建actionTypes文件,里面定义types的常量并导出
    export const SWITCH_THEME = 'switch_theme';
    
    
    // 在用到action的type的地方,引入刚才定义的常量
    import { SWITCH_THEME } from './store/actionTypes';
    
    // 使用的时候,直接用常量代替字符串
        handleBtnClick(e){
            const action = {
                type:SWITCH_THEME
            }
            store.dispatch(action);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • actionCreators 统一创建 action
      一般来说,action函数都是分散在业务逻辑里边的,但是,当业务逻辑非常复杂的情况下,action到处都是,就会对后期的测试和管理是非常不方便的。所以,我们可以把action拆分到actionCreator里进行统一的创建管理。
    // 在store下创建actionCreators.js文件,我们把action的创建统一放到这个文件里,对action进行统一的管理
    // 主要是为了提高代码的可维护性,方便自动化测试
    import { SWITCH_THEME } from './actionTypes';
    
    // 定义一个常量,是一个函数,该函数返回一个对象,对象包含action的type和值
    export  const switchTheme = (theme) => ({
        type: SWITCH_THEME,
        payload: theme,
    })
    
    // 具体的使用,先引入这些actionCreators 里的action
    import { switchTheme } from './store/actionCreators';
    
    // 然后使用store.dispatch去触发action
        handleBtnClick(e){
            const action = switchTheme(‘dark’);
            store.dispatch(action);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    5.reducer中间件

    在reducer中,action是一个普通的js对象,这种形式叫做同步action,通过store.dispatch()进行分发,但当action为异步的时候,reducer就无法处理,这时,就需要redux-thunk中间件。

    安装:

    npm install redux-thunk
    
    • 1

    配置:


    import thunkMiddleware from 'redux-thunk';
    import { createStore, applyMiddleware } from 'redux'
    const store = createStore(reducer, applyMiddleware(thunkMiddleware))
    export default store
    
    • 1
    • 2
    • 3
    • 4

    action函数:

    function getAdd(){
    	return dispatch => {
                dispatch({
                    type: ADD,
                    payload: axios.get(
                         url: ADD_URL,
                         query: {
                             name: '',
                         },
                    )
                });
            },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6.redux开发者工具

    redux提供了redux-devtools-extension插件,可以对状态变化进行可视化查看

    安装:

    npm install redux-devtools-extension
    
    • 1

    同时在chrome浏览器安装Redux DevTools扩展程序

    配置代码:

     const { createStore } = require('redux');
     // 引入工具插件
     const { composeWithDevTools } = require('redux-devtools-extension');
     const store = createStore(reducer, composeWithDevTools(// 包裹在中间件外部));
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在浏览器中按f12,找到Redux菜单,点击便可以看到:
    在这里插入图片描述

    总结

    createStore 创建store
    store.dispatch(),派发创建的action
    store.getState(),获取到store里的数据内容
    store.subscribe(),订阅store里数据的改变,只要store发生改变,subscribe方法接收的函数,就会被执行。

  • 相关阅读:
    Spring:怨种的我和这玩意死磕到半夜12点20的这件事?
    CSS基础
    Maven快速学习
    网络爬虫中selenium和requests这两个工具有什么区别呢?
    CM72 另类加法
    【PTE-day05 宽字节注入】
    【pytorch】2.2 pytorch 自动求导、 Tensor 与 Autograd
    Jaeger的经典BUG原创
    【CV】第 4 章:介绍卷积神经网络
    [附源码]java毕业设计智能超市导购系统
  • 原文地址:https://blog.csdn.net/weixin_44887137/article/details/126035932