aiyoudiao aiyoudiao
  • JavaScript
  • Vue
  • React
  • 低代码
  • 线性系统
  • 暂未分类
  • LeetCode
  • 算法
  • 数据结构
  • 设计模式
  • Other
  • PMP
  • Office
  • 面试
  • Bash
  • 流年往事
  • 经验片段
  • 读书杂感
  • 归档
  • 分类
  • 标签
  • 简介
  • 收藏
  • 有趣
  • 文档

码二

扫微信二维码,认识一下码二吧😉。
  • JavaScript
  • Vue
  • React
  • 低代码
  • 线性系统
  • 暂未分类
  • LeetCode
  • 算法
  • 数据结构
  • 设计模式
  • Other
  • PMP
  • Office
  • 面试
  • Bash
  • 流年往事
  • 经验片段
  • 读书杂感
  • 归档
  • 分类
  • 标签
  • 简介
  • 收藏
  • 有趣
  • 文档
  • JavaScript

  • vue

  • react

    • 16_4

      • React16_4整理-开篇
      • React16_4整理-TodoList
      • React16_4整理-上阶
      • React16_4整理-Redux开篇
        • 前言
        • Redux 概念简述
        • Redux 的工作流程
        • 使用 antd 编写 TodoList 页面布局
        • 创建 redux 中的 store
        • Action 和 Reducer 的编写
        • 使用 Redux 完成 TodoList 删除功能
        • ActionTypes 的拆分
        • 使用 actionCreator 统一创建 action
        • 总结
          • Reducer 必须是纯函数
          • Redux 中核心的 API
        • 拓展
      • React16_4整理-Redux上阶
      • React16_4整理-实战
    • react心得
    • react设计的哲学
    • react上手知识点(上篇)
    • react上手知识点(下篇)
    • antd
  • 低代码

  • 读书会

  • 线性代数

  • docker

  • auto

  • 杂记

  • 笔记
  • react
  • 16_4
aiyoudiao
2022-04-13

04.React16_4整理-Redux开篇.md

# 前言

React 默认没带数据流(状态管理),那些实现了数据流的库不光可以在react中使用,也可以在vue中使用。
在react中flux叫rflux,flux中有多个store。
redux与flux不同,它只有一个单一的store。整个应用的state存储在一个单一的store树中。
mbox是一个状态管理机制,是全自动的,action一改变state,views上就直接发生变化,不需要你像redux一样去写reducer函数了。

这篇文章主要讲的是redux相关的内容,其它的状态管理库,实现的功能都是一样的,只是使用起来不同,但思想大同小异。学会一个,其它看看官网了就理解了。

# Redux 概念简述

React 是一个简单的轻量级的视图层的框架,内置的组件(同级的组件)传值太麻烦了,而且它需要依赖很多的框架才能去实现大项目的构建。
如果你想使用 React 去做一个大的应用,必须使用一个配套的数据层的框架来结合使用才行,这个数据层的框架可以是 Redux。
将组件中的数据存储到一个公共的区域,其它组件需要数据的话,直接到这个公共的存储区域中拿一下即可。
Redux=Reducer+Flux,Flux 是 13 年开源的时候 FaceBook 放出来和 React 一起使用的数据层框架。Flux 不好用,有人把 Flux 做了一个升级,升级之后就叫 Redux。

# Redux 的工作流程

ReactComponent 、ActionCreators、Strore、Reducers

  1. ReactComponent:借书的人
  2. ActionCreators:借书时说的话
  3. Strore:图书馆的管理员
  4. Reducers:图书记录本

Redux 的工作流程:

  1. 首先 ReactComponent 创建一个ActionCreator命令
  2. 通过ActionCreator命令向Strore发起请求
  3. Strore接收到请求后去Reducers查询对应的数据
  4. 从Reducers查询到对应的数据查询后由Strore将对应的数据返回给ReactComponent

# 使用 antd 编写 TodoList 页面布局

安装 antd

使用命令:npm install antd --save 或者 yarn add antd
使用 antd,引入组件,引入css,直接使用组件即可,可以去官网找对应的组件,复制代码简单使用一下。

import { Input ,Button, List } from 'antd';
import '../node_modules/antd/dist/antd.css';

const data = [
    'Racing car sprays burning fuel into crowd.',
    'Japanese princess to wed commoner.',
    'Australian walks 100km after outback crash.',
    'Man charged over missing wedding girl.',
    'Los Angeles battles huge wildfires.',
    ];

class TodoList extends Component {
    constructor (props) {
        super(props);
    }

    render() {
        return(
            <div style = {{margin: '10px 0px 0px 10px', width: "500px"}}>
                <div>
                <Input placeholder = "请输入内容"  style = {{marginRight: '10px', width: "350px"}}/>
                <Button type = "primary" style = {{width: "120px"}}>Primary</Button>
                <List
                    bordered
                    dataSource = {data}
                    style = {{width: '350px', marginTop: '10px'}}
                    renderItem = {item => (<List.Item>{item}</List.Item>)}
                    />
                </div>
            </div>
        )
    }
}

它常用于开发后台,可以用它开发出很漂亮的后台页面

# 创建 redux 中的 store

首先安装 redux:yarn add redux 或者 npm i redux --save
新建一个store文件夹,新建一个index.js和redcer.js

index.js 图书管理员

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

const store = createStore(reducer);

export default store;

redcer.js 图书记录本

const defaultState = {
    list: [123,321],
    inputValue: '789'
};
export default (state = defaultState,action) => {
    // state中存放的是整个图书馆中存放的书籍的信息
    return state;
}

需要用的时候直接引入这个index.js,然后通过对象.getState()方法,就能够获取到store中的内容了,之后你就可以直接使用数据了。

//import store from './store/index.js'
// 简写成这样也可以
import store from './store';

this.state = store.getState();

引入 store ,直接通过store来获取数据或者修改数据,store是一个公共的数据层对象。

# Action 和 Reducer 的编写

安装谷歌浏览器插件:Redux DevTools

使用浏览器开发人员工具点击选项卡 Redux
如果你没有配置,那么你就将 window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 粘贴到createStore(reducer)的第二个参数中去

    const store=createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());

__REDUX_DEVTOOLS_EXTENSION__也是Redux的一个中间件。

深拷贝一个对象:JSON.parse(JSON.stringify(obj));
首先创建一个 store对象并且传递一个reducer对象进去
reducer实际上一个函数,store在创建的时候将这个函数传递进去了

const defaultState = {
    list: [123,321],
    inputValue: '789'
};

export default (state = defaultState, action) => {
    // 根据行动指令执行对应的操作
    if (action.type === "changeInputValue") {
        // reducer 只能够获取state里面的值 绝对不能修改里面的值
        const newState = JSON.parse(JSON.stringify(state));
        newState.inputValue = action.value;
        return newState;
    }

    if (action.type === "addListItem") {
        const newState = JSON.parse(JSON.stringify(state));
        newState.list.push(newState.inputValue);
        newState.inputValue = "";
        return newState;
    }

    // state中存放的是整个图书馆中存放的书籍的信息
    return state;
}

当store进行dispatch方法调度的时候就会去执行reducer了

handleChange (e) {
    const action = {
        type: "changeInputValue",
        value: e.target.value
    }
    store.dispatch(action);
}

执行reducer会对全局的state进行修改

// 根据行动指令执行对应的操作
if (action.type === "changeInputValue") {
    // reducer 只能够获取state里面的值 绝对不能修改里面的值
    const newState = JSON.parse(JSON.stringify(state));
    newState.inputValue = action.value;
    return newState;
}

你可以通过store.getState()来获取全局的state对象

this.state = store.getState();
console.log(store.getState());

你可以通过store.subscribe来进行监听全局 store 的改变,传递进去的回调函数中你可以调用this.setState()来让页面的组件重新渲染

this.handleStoreChange = this.handleStoreChange.bind(this);
// 监听 store中的状态改变
store.subscribe(this.handleStoreChange);

handleStoreChange () {
    console.log("store changed");
    this.setState(store.getState());
}

最后就达到了使用 redux 中 store 里的全局状态进行传值的目的了。

# 使用 Redux 完成 TodoList 删除功能

遍历生成 item 的时候,绑定事件并传递对应的下标,通过 distach 方法进行指令的传递,reducer 中根据执行进行全局状态的间接更改,最后组件中监听全局状态的方法里调用 this.setState(store.getState())重新渲染组件。

# ActionTypes 的拆分

为了防止的你 action.type 中的字符串写错,你可以定义一个常量与对应的字符串相对应,这样相当于定义了一个规范,不仅利于编写,也利于排错。
你创建一个单独的文件,里面存放这些字符串对应的常量,页面中也可以引入这个文件,reducer 中也可以引入这个文件。
这样一来,你不用担心页面或者 reducer 中的字符串写错了而导致无法达到预期的效果了。

# 使用 actionCreator 统一创建 action

将所有的 action 进行统一的管理,这么做的好处是分层,这样利于管理,可以提高代码的可维护性,很像三层架构中模型层、数据访问层、业务逻辑层里的数据访问层。

这样一想,UI 组件就是 UI 层,容器组件就是业务逻辑层,模型层和数据访问层就是Redux中的reducer、store、actionCretor(就像EntityFrameWork通过linq来操作数据库一样)。

并且做自动化测试的时候也会很方便。使用方法来进行管理,每一个action对应一个方法,页面组件只需要调用对应的方法传递数据即可,将对应的指令封装到方法中了,你可以调用方法返回指令,也可以直接在那个方法中直接调用store.disptach(指令)。

React中 数据与视图分离,但是JS逻辑和视图是混在一起的。

# 总结

store 是唯一的,在 store 文件夹下的 index.js 文件被创建,全局共享一个,这里面使用一个单例模式。

只有 store 能够改变自己的内容,不要在reducer.js中去改变state,你只能深度克隆state,然后修改你newState后再return newState,这时候store接收到你的返回的newState之后就会去改变自己的state了。这是一个规范,就是这么定的。

# Reducer 必须是纯函数

纯函数指的是,给定固定的输入,就一定会有固定的输出,而且不会有任何副作用。
也就是给定state和action就会返回newState,但是newState中的属性,是根据state和action来进行确定的,不会受到其它的影响也不能受到其它的影响,如果受到了就不是纯函数了。
只要一个函数中存在 与日期相关的函数或者有setTimeOut就不再是一个纯函数了,因为这些会让这个函数受到其它的影响,不再是固定的输入就有固定的输出。
Reducer 里面不能有异步的操作和与时间相关的操作,对方法传递进来的参数直接做修改就是副作用,Reducer中不允许有副作用。

# Redux 中核心的 API

createStore 用来创建 store
store.dispatch用来派发action,store会接收这个action,并且根据它来进行state的改变
store.getState 获取store中的state
store.subscribe 用来监听store中state的变化

只要store发生改变,就会触发subscribe中的回调函数

# 拓展

以上已经把redux的基础使用做了一下了解,那么简单拓展一下flux和mbox的设计思想。

flux

UI产生动作消息,将动作传递给分发器。(这个动作就是 比如 点击一个按钮或者ajax返回数据) 分发器广播给所有store。(以广播的方式告诉所有store。) 订阅的store做出反应,传递新的state给UI。
在react中flux叫rflux,flux中有多个store。

redux

redux与flux不同,它只有一个单一的store。整个应用的state存储在一个单一的store树中。
state状态为只读,你不能直接修改state,应该要通过action触发state修改。
得使用纯函数进行状态修改,需要你写reducers纯函数来进行处理,reducer通过当前状态树和action来进行计算,返回一个新的state。(这个reducer可以当它是一个merge函数,merge完了之后返回一个新的state来更新掉那个旧的。)
不过如果一个应用的state都存到一个store中,那么效率就会很低,于是它提出了一个分支的概念,不同的state放到不同的分支上。

redux:https://react-redux.js.org/ (opens new window)

flux 和 redux不同

flux和redux都可以作为react的状态管理,flux是多store,redux是单store。
flux有调度器来进行事件处理,redux依赖reducer来实现事件处理。
flux的state可以直接修改,redux 的state不能直接修改,要通过reducer进行state的merge方式来产生一个新的state。

mbox

mbox是一个状态管理机制,是全自动的,action一改变state,views上就直接发生变化,不需要你像redux一样去写reducer函数了。
定义状态并使其可观察,使用修饰符@observer来使其可观察。
创建视图以响应状态变化。
更改状态(自动响应UI变化)。

mobx:https://cn.mobx.js.org/ (opens new window)

#react#redux
上次更新时间: 10年18月2023日 01时57分53秒
React16_4整理-上阶
React16_4整理-Redux上阶

← React16_4整理-上阶 React16_4整理-Redux上阶 →

最近更新
01
01.数据结构导论一览.md
10-16
02
30.2023年06月04日.md
06-04
03
08.与测量相关.md
05-06
更多文章>
Theme by Vdoing | Copyright © 2017-2023 aiyoudiao 码二 备案号: 鄂ICP备2022002654号-1