系列文章目录

第一章:React基础知识(React基本使用、JSX语法、React模块化与组件化)(一)
第二章:React基础知识(组件实例三大核心属性state、props、refs)(二)
第三章:React基础知识(事件处理、受控组件与非受控组件、高阶函数、组件的生命周期)(三)
第四章:React脚手架应用(创建脚手架、代理配置、ajax相关、组件通信)(四)
第五章:react-router5路由相关一(路由相关概念、基本使用、NavLink与NavLink的封装、Switch的使用、严格匹配、路由重定向、路由组件与一般组件的区别)(五)
第六章:react-router5路由相关二(嵌套路由、路由传参、replace、编程式路由导航、withRouter的使用、BrowserRouter与HashRouter的区别)(六)
第七章:React-Router6路由相关一(路由的基本使用、重定向、NavLink·、路由表、嵌套路由)(七)
第八章:React-Router6路由相关二(路由传参、编程式路由导航、路由相关hooks)(八)
第九章:React相关扩展一(setState、lazyLoad、Hooks相关)(九)
第十章:React相关扩展二(Fragment、Content、组件优化、render props、错误边界)(十)
第十一章:Redux相关知识(什么是redux、redux的工作原理、redux的核心概念、redux的基本使用)(十一)
第十二章:React-Redux相关知识(什么是react-redux、react-redux的原理、react-redux相关API、react-redux的基本使用)(十二)


文章目录

  • 系列文章目录
    • 一、什么是Redux
      • 1.1 概念
      • 1.2 何时使用?
      • 1.3 redux的工作原理
    • 二、核心概念
      • 2.1 state
      • 2.2 action
      • 2.3 reducer(重要)
      • 2.4 store
      • 2.5 dispatch
      • 2.6 subscribe(listener)
    • 三、redux的基本使用(搭建redux环境)

一、什么是Redux

1.1 概念

  • Redux 是 JavaScript应用的状态容器,提供可预测的状态管理。可以开发出行为稳定可预测的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。
  • Redux 是一个使用叫做“action”的事件来管理和更新应用状态的模式和工具库,它以集中式Store的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。
  • Redux提供的模式和工具使您更容易理解应用程序中的状态何时、何地、为什么以及如何更新,以及当这些更改发生时您的应用程序逻辑将如何表现。
  • 类似于vuex 但是不同于vuex,可以对状态进行管理。

1.2 何时使用?

  • 在应用的大量地方,都存在大量的状态
  • 应用状态会随着时间的推移而频繁更新
  • 更新该状态的逻辑可能很复杂
  • 中型和大型代码量的应用,很多人协同开发
  • 不同身份的⽤户有不同的使⽤⽅式(⽐如普通⽤户和管理员)
  • 与服务器⼤量交互,或者使⽤了WebSocket
  • View要从多个来源获取数据
  • 某个组件的状态,需要共享某个状态需要在任何地⽅都可以拿到
  • ⼀个组件需要改变全局状态
  • ⼀个组件需要改变另⼀个组件的状态

1.3 redux的工作原理


  • 页面初始渲染时:

    • 使用最顶层的 root reducer 函数创建 Redux store
    • store 调用一次 root reducer,并将返回值保存为它的初始 state
    • 当 UI 首次渲染时,UI 组件访问 Redux store 的当前 state,并使用该数据来决定要呈现的内容。
    • 同时监听store 的更新,以便他们可以知道 state 是否已更改。
  • 页面更新渲染时:

    • dispatch 一个 actionRedux store,例如 dispatch({type:'counter/increment'})
    • store之前的 state当前的 action 再次运行 reducer 函数,并将返回值保存为新的 state
    • store 通知所有订阅过的 UI通知它们 store 发生更新
    • 每个订阅过 store 数据的 UI 组件都会检查它们需要的 state 部分是否被更新。
    • 发现数据被更新的每个组件都强制使用新数据重新渲染,紧接着更新网页

二、核心概念

应用的整体全局状态以对象树的方式存放于单个 store唯一改变状态树的方法创建 action,一个描述发生了什么的对象,并将其 dispatch 给 store。 要指定状态树如何响应 action 来进行更新,你可以编写纯 reducer 函数,这些函数根据旧 state 和 action 来计算新 state

2.1 state

  • 托管给redux管理的状态
  • 示例代码:
let state = { todos:[], params:{}
}

2.2 action

  • Action

    • Action 描述当前发⽣的事情。改变State的唯⼀办法,就是使⽤Action。它会运送数据到 Store。
    • Action 本质上是 JavaScript 普通对象。action必须使⽤⼀个字符串类型的 type字段表示将要执⾏的动作
    • type 字段是一个字符串,给这个 action 一个描述性的名字,比如"todos/todoAdded"。
    • action对象可以有其他字段,其中包含有关发生的事情的附加信息。按照惯例,我们将该信息放在名为data的字段中,也可放放到其他属性中,不过最好放到data中。
    • 示例代码:
    { type: 'ADD_TODO', text: '去游泳馆' }
    { type: 'TOGGLE_TODO', index: 1 }
    { type: 'SET_VISIBILITY_FILTER', filter: 'completed' }
    
  • Action Creator

    • action creator 是一个创建并返回一个 action 对象的函数。它的作用是让你不必每次都手动编写 action对象

    • 示例代码:

    const addTodo = data => ({type: 'todos/todoAdded',data})
    

2.3 reducer(重要)

  • reducer一个函数接收当前的state和一个action 对象,必要时决定如何更新状态,并返回新状态。函数签名是:(state, action) => newState。可以将reducer 视为一个事件监听器,它根据接收到的action(事件)类型处理事件。

  • Reducer 必需符合以下规则:

    • 仅使用 state 和 action 参数计算新的状态值
    • 禁止直接修改 state。必须通过复制现有的 state 并对复制的值进行更改的方式来做不可变更新
    • 禁止任何异步逻辑、依赖随机值或导致其他“副作用”的代码
  • reducer 函数内部的逻辑通常遵循以下步骤:

    • 检查 reducer 是否联系这个 action

      • 如果是,则复制 state,使用新值更新 state 副本,然后返回新 state
      • 否则,返回原来的 state 不变
  • 示例代码:

    // 初始化状态
    const initialState = { value: 0, index: 1 }function counterReducer(preState=initialState, action) {//从action对象中获取:type、dataconst {type,data} = action//根据type决定如何加工数据switch (type) {case 'increment': //如果是加return { ...preStatevalue:preState.value + data}case 'decrement': //若果是减return { ...preStatevalue:preState.value - data}default:// 返回prestate 不变return preState}
    }
    

2.4 store

  • 当前 Redux 应用的状态存在于一个名为 store 的对象中。store 是通过传入一个reducer来创建的,并且有一个getState 的方法,它返回当前状态值

  • Store 就是保存数据的地⽅,可以把它看成⼀个容器。整个应⽤只能有⼀个Store。Redux提供createStore这个函数,⽤来⽣成Store

  • 示例代码:

    //引入createStore,专门用于创建redux中最为核心的store对象
    // 旧版本的引入
    // import {createStore} from 'redux'
    // 新版本的引入
    import { legacy_createStore as createStore } from 'redux'
    //引入为Count组件服务的reducer
    import reducer from './reducer'
    //暴露store
    export default createStore(reducer)
    /* 如果该仓库用多个reducer,则使用combineReducers函数来合并reducer,可以通过combineReducers组合多个Reducer,然后通过createStore来创建状态机。*/
    const store2=createStore(combineReducers({todos,counter,
    }));
    

    或者直接使用@reduxjs/toolkit包中的configureStore方法来生成store

    import { configureStore } from '@reduxjs/toolkit'
    const store = configureStore({ reducer})
    

    仓库创建好了之后,将store引入到需要使用仓库的组件中。

    import store from './store/index.js'
    // 分发动作
    store.dispatch({type:'',data:''})
    // 获取仓库数据
    store.getState();
    

2.5 dispatch

  • Redux store 有一个方法叫 dispatch更新 state 的唯一方法调用 store.dispatch() 并传入一个action对象。store 将执行所有reducer函数并计算出更新后的state,调用 getState()
    可以获取新state。

  • 示例代码

    store.dispatch({ type: 'counter/increment' })
    console.log(store.getState())
    // {value: 1}
    
  • dispatch 一个 action 可以形象的理解为 "触发一个事件"。发生了一些事情,我们希望 store
    知道这件事。Reducer 就像事件监听器一样,当它们收到关注的 action 后,它就会更新 state 作为响应。 我们通常调用 action creator 来调用 action

  • 示例代码

    const increment = () => {return {type: 'counter/increment'}
    }
    // 分发动作
    store.dispatch(increment())
    console.log(store.getState())
    

2.6 subscribe(listener)

  • 添加一个变化监听器。每当dispatch action 的时候就会执行,state
    树中的一部分可能已经变化。你可以在回调函数里调用 getState() 来拿到当前 state。你可以在变化监听器里面进行
    dispatch(),如果需要解绑这个变化监听器,执行 subscribe 返回的函数即可。

  • 参数listener (Function):当 dispatch action 的时候都会执行的回调。state 树中的一部分可能已经变化。你可以在回调函数里调用 getState() 来拿到当前 state。

  • 返回值(Function): 一个可以解绑变化监听器的函数。

    // 监听方法一
    store.subscribe(() => {this.setState({...store.getState()});
    }); //订阅者做的事情// 监听方法二
    store.subscribe(()=>{ReactDOM.render(<App/>,document.getElementById('root'))
    })
    

三、redux的基本使用(搭建redux环境)

  • 安装

    npm install redux
    
  • 主要API

    • createStore(reducer, [preloadedState], [enhancer]) 创建仓库
    • combineReducers(reducers) 合并reducer
    • applyMiddleware(...middlewares) 应用中间件
  • store相关API

    • store.getState() 获取仓库中的状态
    • store.dispatch(action) 分发到某个动作
    • store.subscribe(listener) 订阅仓库内状态更新
    • replaceReducer(nextReducer) 替换reducer
  • 代码案例片段:
    index.js

    import React from 'react'
    import ReactDOM from 'react-dom'
    import App from './App'
    import store from './redux/store'ReactDOM.render(<App/>,document.getElementById('root'))store.subscribe(()=>{ReactDOM.render(<App/>,document.getElementById('root'))
    })
    

    App.js

    import React, { Component } from 'react'
    import Count from './components/Count'export default class App extends Component {render() {return (<div><Count/></div>)}
    }

    redux/count_action.js(该文件专门为Count组件生成action对象)

    //同步action,就是指action的值为Object类型的一般对象
    export const createIncrementAction = data => ({type:'increment',data})
    export const createDecrementAction = data => ({type:'decrement',data})//异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的。
    export const createIncrementAsyncAction = (data,time) => {return (dispatch)=>{setTimeout(()=>{dispatch(createIncrementAction(data))},time)}
    }
    

    redux/count_reducer.js

    /* 1.该文件是用于创建一个为Count组件服务的reducer,reducer的本质就是一个函数2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)
    */
    const initState = {value:0,index:1
    }
    //初始化状态
    export default function countReducer (preState = initState, action) {console.log('preState:',preState);console.log('action:',action);//从action对象中获取:type、dataconst { type, data } = action//根据type决定如何加工数据switch (type) {case 'increment': //如果是加return {...preState,value: preState.value + data}case 'decrement': //若果是减return {...preState,value: preState.value - data}default:return preState}
    }
    

    redux/store.js

    /* 该文件专门用于暴露一个store对象,整个应用只有一个store对象
    *///引入createStore,专门用于创建redux中最为核心的store对象
    // 旧版
    // import { createStore } from 'redux'
    //新版
    import { legacy_createStore as createStore, applyMiddleware } from 'redux'
    //引入为Count组件服务的reducer
    import countReducer from './count_reducer'
    //引入redux-thunk,用于支持异步action
    import thunk from 'redux-thunk'
    //暴露store
    export default createStore(countReducer, applyMiddleware(thunk))
    

    components/Count.jsx

      import React, { Component } from 'react'
    //引入store,用于获取redux中保存状态
    import store from '../../redux/store'
    //引入actionCreator,专门用于创建action对象
    import {createIncrementAction,createDecrementAction,createIncrementAsyncAction
    } from '../../redux/count_action'export default class Count extends Component {state = {carName:'奔驰c63'}/* componentDidMount(){//检测redux中状态的变化,只要变化,就调用renderstore.subscribe(()=>{this.setState({})})} *///加法increment = ()=>{const {value} = this.selectNumberstore.dispatch(createIncrementAction(value*1))}//减法decrement = ()=>{const {value} = this.selectNumberstore.dispatch(createDecrementAction(value*1))}//奇数再加incrementIfOdd = ()=>{const {value} = this.selectNumberconst count = store.getState()if(count % 2 !== 0){store.dispatch(createIncrementAction(value*1))}}//异步加incrementAsync = ()=>{const {value} = this.selectNumber// setTimeout(()=>{store.dispatch(createIncrementAsyncAction(value*1,500))// },500)}render() {return (<div><h1>当前求和为:{store.getState()}</h1><select ref={c => this.selectNumber = c}><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;<button onClick={this.incrementAsync}>异步加</button>&nbsp;</div>)}
    }
    

    运行结果:

Redux相关知识(什么是redux、redux的工作原理、redux的核心概念、redux的基本使用)(十一)相关推荐

  1. 路由相关知识,静态路由、默认路由、浮动路由的概念以及基本设置

    路由相关知识,静态路由.默认路由.浮动路由的概念以及基本设置 选取最佳路由时的标准 路由表 路由表的形成 静态路由概念 静态路由的优点和缺点 默认路由 浮动路由 路由协议分类 静态路由.默认路由.浮动 ...

  2. 光立方原理讲解_电工基础知识——光电耦合器的分类、工作原理和检测以及应用...

    大家好,今天我们主要讲解一下光电耦合器的分类.工作原理和检测以及其在生活中的应用. 光电耦合器 1.光电耦合器的分类 光电耦合器分两类:普通光电耦合器和线性光电耦合器.普通光电耦合器的输入.输出间传输 ...

  3. 《涨知识啦30》-太阳能电池基本工作原理

    当光照射到PN结上时,PN结区会产生电子-空穴对,结区中的部分非平衡载流子将以复合的形式湮灭,没有参与复合的非平衡载流子则在PN结区电场的作用下进行输运:电子进入N区,空穴进入P区,因此N区中过剩的电 ...

  4. 硬件基础知识--(10)三极管的工作原理

    一.很多初学者都会认为三极管是两个 PN 结的简单凑合(如图1).这种想法是错误的,两个二极管的组合不能形成一个三极管.我们以 NPN 型三极管为例(见图 2 ),两个 PN 结共用了一个 P 区 - ...

  5. 《涨知识啦29》-DBR的工作原理及其在VCSEL中的作用

    分布式布拉格(Distributed Bragg Reflection,简称DBR)反射镜是垂直腔面发射激光器(Vertical-Cavity Surface-Emitting Laser,简称VCS ...

  6. Redux 主要知识学习总结

    文章出自个人博客 https://knightyun.github.io/2020/11/29/js-redux-summary,转载请申明 概念 Redux 作为一个状态管理器,可以应用于多种 we ...

  7. 【React.js 06】Redux基础知识

    Redux是一个专注于状态管理的库,和React是解耦的,用Angular和Vue都可以使用Redux.其具有一个单一状态,单向数据流的特性. Redux概念 redux有一个store,记录所有的s ...

  8. redux相关学习资源

    很多学习资料,直接在SF.掘金搜索关键词redux源码等可以获得. redux参考版本3.6或3.7.2   redux-thunk看1.0.1 1.redux源码分析之四:compose函数    ...

  9. Redux 核心概念

    http://gaearon.github.io/redux/index.html ,文档在 http://rackt.github.io/redux/index.html .本文不是官方文档的翻译. ...

最新文章

  1. void main()是错的!
  2. 2021年人工神经网络第一次作业要求
  3. 【报错】No match for argument: mysql-community-server Error: Unable to find a match: mysql-community-s
  4. 二分法(三种基本模版)
  5. python怎么编辑文件_如何使用python中的方法对文件进行修改文件名
  6. 写代码需要注意的几方面
  7. 爬虫+pyecharts数据分析实例:当当网
  8. Spring beans配置方案(二) 学习笔记
  9. 未来网闸的发展趋势(实际应用需求,解决方案)
  10. [Cocos Creator] 制作简版消消乐(四):实现消除算法
  11. ev3无需使用计算机编程,Legoev3机器人怎么编程.docx
  12. python动态调用函数
  13. 您的Window许可证即将过期的一种解决办法
  14. 3小时入门微信小程序开发 --公开课学习笔记
  15. CCF [201703-1] 分蛋糕(C++)
  16. 「解析」正则化 DropPath
  17. wifi mesh组网
  18. 一文掌握GSEA,超详细教程!
  19. Kali/Ubuntu GVM (openvas)安装及使用
  20. 虚幻引擎学习笔记——Month1 Week1

热门文章

  1. svg动画,渐变,阴影
  2. 计算机联锁驱采故障查找,EI32-JD型计算机联锁驱动、采集故障处理方法.pdf
  3. qq空间秒赞技术是如何实现的?
  4. Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.properties.Configurati
  5. ios沙箱软件_iOS 开发之沙盒机制
  6. python围圈报数 青少年编程电子学会python编程等级考试三级真题解析2021年6月
  7. 一个 Web 项目的创建及配置(完整版)
  8. 怀旧服一直显示正在登录服务器,怀旧服显示正在登录游戏服务器
  9. linux signal历史log,nginx错误signal process started错误error.log日志显示signal process started错误解决方法...
  10. venv 创建虚拟环境并激活