0


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
import { createStore } from 'redux'
const store = createStore(reducer)

action

这个

action

指的是视图层发起的一个操作,告诉

Store

我们需要改变。比如用户点击了按钮,我们就要去请求列表,列表的数据就会变更。每个

action

必须有一个

type

属性,这表示

action

的名称,然后还可以有一个

payload

属性,这个属性可以带一些参数,用作

Store

变更:

const action = {
  type: 'ADD_ITEM',
  payload: 'new item', // 可选属性
}

上面这个例子就定义了一个名为

ADD_ITEM

Action

,它还携带了一个

payload

的参数。

Redux

可以用

Action Creator

批量来生成一些

Action

Reducer

在上面我们定义了一个

Action

,但是

Action

不会自己主动发出变更操作到

Store

,所以这里我们需要一个叫

dispatch

的东西,它专门用来发出

action

,不过还好,这个

dispatch

不需要我们自己定义和实现,

redux

已经帮我们写好了,在

redux

里面,

store.dispatch()

View

发出

Action

的唯一方法。

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

dispatch

发起了一个

action

之后,会到达

reducer

,那么这个

reducer

用来干什么呢?顾名思义,这个

reducer

就是用来计算新的

store

的,

reducer

接收两个参数:当前的

state

和接收到的

action

,然后它经过计算,会返回一个新的

state

。(前面我们已经说过了,不能直接更改

state

,必须通过返回一个新的

state

来进行变更。)

const reducer = function(prevState, action) {
  ...
  return newState;
};

这个

reducer

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

可以看到,我们在创建

store

的时候,我们在

createStore

里面传入了一个

reducer

参数,在这里,我们就是为了,每次

store.dispatch

发送一个新的

action

,

redux

都会自动调用

reducer

,返回新的

state

这里先看一个例子

实现一个计算功能

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

store.js中

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

reducers.js文件中

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

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

在count.js中

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

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

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

import React, { Component } from 'react';
// 引入状态
import store from './redux/store.js'
class count extends Component {
   state={
   
    }
    // 组件挂载时调用
    componentDidMount(){
      // 当Redux状态变化时,强制更新rendar,让页面进行渲染
      store.subscribe(() => {
        this.setState({})
      })
     
    }
    // 加法
    add1=() => {
      const {value}=this.select
     store.dispatch({type:'add1',data:value*1})
    
    }
    add2=() => {
       const {value}=this.select
      //console.log(typeof value)//string
      store.dispatch({type:'add2',data:value*1})
    }
    add3=() => {
       const {value}=this.select
      //console.log(typeof value)//string
      const count=store.getState() 
      //string+number=string 所以要把string转number 
      if(count%2!==0) {
         store.dispatch({type:'add1',data:value*1})
     }else{
        alert('不符合奇数要求')
      }
    }
    add4=() => {
       const {value}=this.select
      //console.log(typeof value)//string
    
      //string+number=string 所以要把string转number 
      setInterval(()=>{
       store.dispatch({type:'add1',data:value*1})
      },2000) 
     
    }
  render() {
   
    return (
      <div>
        {/* 获取状态 */}
        <h4>{store.getState()}</h4>
        <select ref={(c)=>{this.select=c}}>
          <option value='1'>1</option>
          <option value='2'>2</option>
          <option value='3'>3</option>
          <option value='4'>4</option>
        </select>&nbsp;
        <button onClick={this.add1}>+</button>&nbsp;
        <button onClick={this.add2}>-</button>&nbsp;
        <button onClick={this.add3}>当前求和为奇数再加</button>&nbsp;
        <button onClick={this.add4}>异步加</button>
      </div>
    );
  }
}

export default count;

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

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

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

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

action.js

这里实现加减操作

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

在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中

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

在action.js中

返回一个函数

export const ceactAsyncAdd1Action=(data,time)=>{
  // 返回函数异步action
   return () => {
     setTimeout(() => {
      store.dispatch(ceactAdd1Action(data))
     },time)
   }
}

四.react-rudex

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

标签: html 前端 react.js

本文转载自: https://blog.csdn.net/qq_56989560/article/details/125409153
版权归原作者 Mr.指尖舞者 所有, 如有侵权,请联系我们删除。

“Redux——详解”的评论:

还没有评论