React之Redux


简介

redux 统一保存数据,在隔离了数据与UI的同时,负责处理数据的绑定。

在这里插入图片描述


什么时候需要使用Redux

  • 组件需要共享数据(状态state)的时候
  • 某个状态需要在任何地方都可以被随时访问的时候
  • 某个组件需要改变另一个组件的状态的时候

具体使用场景如:语言切换、黑暗模式切换、用户登录全局数据共享…


Redux架构

  1. redux是的诞生是为了给 React 应用提供「可预测化的状态管理」机制。
  2. Redux会将整个应用状态(其实也就是数据)存储到到一个地方,称为store
  3. 这个store里面保存一棵状态树(state tree)
  4. 组件改变state的唯一方法是通过调用store的dispatch方法,触发一个action,这个action被对应的reducer处理,于是state完成更新
  5. 组件可以派发(dispatch)行为(action)给store,而不是直接通知其它组件
  6. 其它组件可以通过订阅store中的状态(state)来刷新自己的视图

.
在这里插入图片描述


Redux工作流

自己画了个比较粗浅的流程图,可以结合实际发朋友圈的场景来理解:
在这里插入图片描述

  • Store:是Redux中带有推送功能的数据仓库
  • Reducer:是帮助Store处理(初始化、修改、删除)数据的方法
  • Actions:是数据更新的指令,会告诉Reducer如何去处理数据
  • Dispatch:是发送数据更新的指令(提交Actions)的过程

Redux三大原则

  1. 单一数据源
  2. state是只读的,修改state唯一方法就是触发action
  3. 使用纯函数reducer来修改state,返回一个新的statestore

Redux简单流程

// redux三大块 store action reducer

import { createStore } from 'redux';

const initState = {
  count: 0,
}

// 1、action用来修改store
const action1 = { type: 'INCREMENT' }
const action2 = { type: 'DECREMENT' }
const action3 = { type: 'ADDNUM', num: 10 }
const action4 = { type: 'REDUCENUM', num: 20 }

// 2、reducer是连接store和action,返回新的state给store
const reducer = (state = initState,action) => {
  switch (action.type) {
    case "INCREMENT": return {...state,count: state.count + 1}
    case "DECREMENT": return {...state,count: state.count - 1}
    case "ADDNUM": return {...state,count: state.count + action.num }
    case "REDUCENUM": return {...state,count: state.count - action.num }
  }
}
// 3、store保存状态,创建一个对象即可
const store = createStore(reducer);

// 5: 在派发之前监听store的变化
store.subscribe(() => {
  console.log(`count:${store.getState().count}`);
})

// 4、派发action
store.dispatch(action1)
store.dispatch(action2)
store.dispatch(action3)
store.dispatch(action4)

Redux流程详解

在这里插入图片描述
在src下新建redux文件夹

1. Store

在redux文件夹下新建store.ts

import { createStore } from 'redux';
import reducer from './reducer';

const store = createStore(reducer); // createStore可以帮助我们创建一个store

export default store;

store就是redux的一个数据中心,简单的理解就是我们所有的数据都会存放在里面,然后在界面上使用时,从中取出对应的数据。因此最开始,我们要创建一个这样的store,redux提供了createStore方法。

2. Reducer

在redux文件夹下新建reducer.ts

import i18n from 'i18next';

const defaultState = {
    language: 'zh',
    languageList: [
        { name: '中文', code: 'zh' },
        { name: 'English', code: 'en' },
        { name: '新增语言', code: 'add' }
    ],
};

const reducer = (state = defaultState, action) => {
    switch (action.type) {
        case 'CHANGELANGUAGE': // 切换语言
            i18n.changeLanguage(action.value);
            return { ...state, language: action.value }; // 不能直接修改旧的state,而是返回一个新的state来替代
        case 'ADDLANGUAGE': // 新增语言
            return { ...state, languageList: [...state.languageList, action.value] };
        default:
            return state;
    }
};

export default reducer;

Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。

3. Action

在redux文件夹下新建action.ts

export const changeLanguage = value => ({ type: 'CHANGELANGUAGE', value });

export const addLanguage = value => ({ type: 'ADDLANGUAGE', value });

Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。

4. 组件中使用

语言切换组件Language.tsx

import React from 'react';
import { withRouter } from 'react-router-dom';
import store from '../../redux/store';
import { changeLanguage, addLanguage } from '../../redux/action';

class LanguageComponents extends React.Component{
    constructor(props) {
        super(props);
        const storeState = store.getState();
        this.state = {
            language: storeState.language,
            languageList: storeState.languageList
        }
        
		// 订阅store  store发生改变时,自动触发storeChange方法
        store.subscribe(this.storeChange.bind(this));
    }
    storeChange() {
        let storeState = store.getState();  // 得到当前state状态,包含所有store属性
        this.setState({
            language: storeState.language,
            languageList: storeState.languageList
        });  // 重新渲染 View
    }
    clickHandler = (e) => {
  	    // 通过 store.dispatch() 将 action 传到 store
        let val = e.key;
        if (val == 'add') {
            store.dispatch(addLanguage({ name: '新的语言', code: 'new_lang' }));
        } else {
            store.dispatch(changeLanguage(val));
        }
    }
    render() {
        return (
            <div>
                <Menu onClick={this.clickHandler}>
                    {this.state.languageList.map((item) => {
                        return <Menu.Item key={item.code}>{item.name}</Menu.Item>
                    })}
                </Menu>
            	当前语言是{this.state.language === 'zh' ? '中文' : 'English'}
            </div >
        );
    }
};

export const Language = withRouter(LanguageComponents);

store包含的方法:

  • store.dispatch 帮助我们派发action,这个action会传递给store
  • store.getState 获取到store里面所有的数据内容
  • store.subscribe 可以让我们订阅(监听) store的改变 只要store发生改变, 这个方法的回调函数就会执行
posted @ 2022-07-20 18:15  猫老板的豆  阅读(248)  评论(0编辑  收藏  举报