• Redux——详解


    一.初识Redux

    相当于vue中的vuex

    1.redux 是一个独立专门用于做状态管理的 JS 库(不是 react 插件库)
    2.它可以用在 react, angular, vue 等项目中, 但基本与 react 配合使用
    3.作用: 集中式管理 react 应用中多个组件共享的状态
     

    看看Redux的工作原理图

    如果要进行加一操作流程如下:

    值得注意的是:Reducers不仅 可以进行加工状态,还可以进行初始化状态(undefinded)

    二,核心概念

    Store

    在 redux 里面,只有一个Store,整个应用需要管理的数据都在这个Store里面。这个Store我们不能直接去改变,我们只能通过返回一个新的Store去更改它。redux提供了一个createStore来创建state

    1. import { createStore } from 'redux'
    2. const store = createStore(reducer)

    action

    这个 action 指的是视图层发起的一个操作,告诉Store 我们需要改变。比如用户点击了按钮,我们就要去请求列表,列表的数据就会变更。每个 action 必须有一个 type 属性,这表示 action 的名称,然后还可以有一个 payload 属性,这个属性可以带一些参数,用作 Store 变更:

    1. const action = {
    2. type: 'ADD_ITEM',
    3. payload: 'new item', // 可选属性
    4. }

    上面这个例子就定义了一个名为ADD_ITEMAction,它还携带了一个payload的参数。 Redux 可以用 Action Creator 批量来生成一些 Action。 

    Reducer

    在上面我们定义了一个Action,但是Action不会自己主动发出变更操作到Store,所以这里我们需要一个叫dispatch的东西,它专门用来发出action不过还好,这个dispatch不需要我们自己定义和实现,redux已经帮我们写好了,在redux里面,store.dispatch()View发出 Action 的唯一方法。

    1. store.dispatch({
    2. type: 'ADD_ITEM',
    3. payload: 'new item', // 可选属性
    4. })

    dispatch 发起了一个 action 之后,会到达 reducer,那么这个 reducer 用来干什么呢?顾名思义,这个reducer就是用来计算新的store的,reducer接收两个参数:当前的state和接收到的action,然后它经过计算,会返回一个新的state。(前面我们已经说过了,不能直接更改state,必须通过返回一个新的state来进行变更。)

    1. const reducer = function(prevState, action) {
    2. ...
    3. return newState;
    4. };

    这个 reducer 是一个纯函数。纯函数的意思是说,对于相同的输入,只会有相同的输出,不会影响外部的值,也不会被外部的值所影响。纯函数属于函数式编程的概念,如果你想了解更多纯函数的概念,请看这里 

    可以看到,我们在创建store的时候,我们在createStore里面传入了一个reducer参数,在这里,我们就是为了,每次store.dispatch发送一个新的action,redux都会自动调用reducer,返回新的state

    这里先看一个例子

    实现一个计算功能

              

    1.先创建一个Redux文件夹,分别创建store.js和reducers.js文件

    store.js中

    1. //引入creacteStore,专门用于创建redux中最核心的store对象
    2. import { legacy_createStore as createStore } from "redux";
    3. //引入为Count组件服务的reducer
    4. import countRedux from './reducers'
    5. const store=createStore(countRedux)
    6. //暴露出去
    7. export default store

    reducers.js文件中

    这块代码参照上面的原理图

    1. //接收两个参数 之前的状态preState,和动作对象action
    2. //const init=0
    3. export default function countRedux(preState,action) {
    4. // 从action对象中拿出:type,data
    5. console.log(preState,action);
    6. const {type,data}=action
    7. // 根据传进来的type判断要进行的操作
    8. switch (type) {
    9. // 如果类型是加,用传进来之前的值+action中的值,返回出去
    10. case 'add1':
    11. return preState+data
    12. case 'add2':
    13. return preState-data
    14. default:
    15. //返回初始化数据
    16. return 0
    17. }
    18. }

    在count.js中

    store.getState()获取reducx中的返回值

     store.dispatch()向redux中发送  第一个参数之前的值  第二个参数值action对象

    store.subscribe()  当Redux状态变化时,强制更新rendar,让页面进行渲染

    1. import React, { Component } from 'react';
    2. // 引入状态
    3. import store from './redux/store.js'
    4. class count extends Component {
    5. state={
    6. }
    7. // 组件挂载时调用
    8. componentDidMount(){
    9. // 当Redux状态变化时,强制更新rendar,让页面进行渲染
    10. store.subscribe(() => {
    11. this.setState({})
    12. })
    13. }
    14. // 加法
    15. add1=() => {
    16. const {value}=this.select
    17. store.dispatch({type:'add1',data:value*1})
    18. }
    19. add2=() => {
    20. const {value}=this.select
    21. //console.log(typeof value)//string
    22. store.dispatch({type:'add2',data:value*1})
    23. }
    24. add3=() => {
    25. const {value}=this.select
    26. //console.log(typeof value)//string
    27. const count=store.getState()
    28. //string+number=string 所以要把string转number
    29. if(count%2!==0) {
    30. store.dispatch({type:'add1',data:value*1})
    31. }else{
    32. alert('不符合奇数要求')
    33. }
    34. }
    35. add4=() => {
    36. const {value}=this.select
    37. //console.log(typeof value)//string
    38. //string+number=string 所以要把string转number
    39. setInterval(()=>{
    40. store.dispatch({type:'add1',data:value*1})
    41. },2000)
    42. }
    43. render() {
    44. return (
    45. <div>
    46. {/* 获取状态 */}
    47. <h4>{store.getState()}</h4>
    48. <select ref={(c)=>{this.select=c}}>
    49. <option value='1'>1</option>
    50. <option value='2'>2</option>
    51. <option value='3'>3</option>
    52. <option value='4'>4</option>
    53. </select>&nbsp;
    54. <button onClick={this.add1}>+</button>&nbsp;
    55. <button onClick={this.add2}>-</button>&nbsp;
    56. <button onClick={this.add3}>当前求和为奇数再加</button>&nbsp;
    57. <button onClick={this.add4}>异步加</button>
    58. </div>
    59. );
    60. }
    61. }
    62. export default count;

    上面代码中生命周期钩子中的强制更新可以进行优化

    在index.js入口文件中进行设置 

    以上这种方式是简写方式,下面进行改造

    观察原理图,上面那个我们忽略了action,下面我们创建action.js文件

     action.js

    这里实现加减操作

    1. /**
    2. * 专门为Count组件生成action对象
    3. */
    4. // 加 箭头函数的简写模式
    5. export const ceactAdd1Action=data=>({type:'add1',data:data})
    6. //减法 常规模式
    7. export function ceactAdd2Action(data){
    8. return {type:'add2',data:data}
    9. }

    在count.js中进行修改

    先进行导入

    import {ceactAdd1Action,ceactAdd2Action} from './redux/action.js'

    修改代码 

    这里省略奇数相加,和异步加  

    三.异步action

    1.什么是异步action?

    有了异步action,那肯定有同步action.一般情况   我们把对象(Object)形式叫做同步action

    函数(function)形式称为异步action ,我们上面的例子action传入的是一个对象,他就是同步的

    举个例子:

    假如去食堂吃饭,1.你等上5min对服务员说上菜(就是上面例子实现异步的方式)

                                  2.你告诉服务员五分钟后上菜,(这就是异步action)

    2.什么时候用?

    当你明确延时任务不想交给自身组件,想交给action时

    3.怎么用?

    安装中间件 配置在store中

    yarn add redux-thunk

     在store.js中配置

    在count.js中

    1. add4=() => {
    2. const {value}=this.select
    3. //console.log(typeof value)//string
    4. //string+number=string 所以要把string转number
    5. store.dispatch(ceactAsyncAdd1Action(value*1,500))
    6. }

     在action.js中

    返回一个函数

    1. export const ceactAsyncAdd1Action=(data,time)=>{
    2. // 返回函数异步action
    3. return () => {
    4. setTimeout(() => {
    5. store.dispatch(ceactAdd1Action(data))
    6. },time)
    7. }
    8. }

    四.react-rudex

    后续会继续补充.........

  • 相关阅读:
    免费IP代理靠谱吗?靠谱的IP代理有哪些?
    程序员的产品思维
    数据库的基本操作
    神经网络各层的作用
    计算机毕业设计springboot+vue基本微信小程序的学生作业管理小程序 uniapp
    【HDFS】Router JMX中的几个与connection相关的metric
    利用化合物名称从PubChempy中批量下载化合物信息
    Java中Long型数据类型对应MySQL数据库中哪种类型?
    遇到bug的解决办法,测试再也不背锅了
    【Hack The Box】linux练习-- Delivery
  • 原文地址:https://blog.csdn.net/qq_56989560/article/details/125409153