美文网首页redux
轻松搞定 -react-redux-基本用法

轻松搞定 -react-redux-基本用法

作者: 云高风轻 | 来源:发表于2021-07-28 21:39 被阅读0次

1. 前言

之前写了几篇关于 reduxreact-redux文章,链接如下
redux-基础
redux-实战
react-redux 基础
react-redux-reducer拆分
但是反应还是似懂非懂,这次我就换种方式再来捋一遍,我就不信,讲不明白,如果看不懂,不是读者们技术不行,是我自己没有讲明白


2. 是什么 what redux

Redux是一个使用叫做“action”的事件来管理更新应用状态的模式和工具库 ;
它以集中式Store(centralized store)的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。

简单来说就是 类似vuex 用来管理应用程序中状态数据的


3. 应用场景

1.在应用的大量地方,都存在大量的状态
2.应用状态会随着时间的推移而频繁更新
3.更新该状态的逻辑可能很复杂
4.中型和大型代码量的应用,很多人协同开发

简单来说就是你有些数据需要多个页面或者组件共享的时候,就该想到状态管理了
react对应的 是 react-reduxmobx,因为这俩比较流行,
多说一句,其实这俩可以在一个项目中同时使用,至于为啥用两个,无非就是可能后来填坑的人,不懂之前的用法,就写一个自己会的而已,虽然我不建议这么做,但是有些外包确实就是这样


4. 环境安装

npm install react-redux

我这里具体是 "react-redux": "^7.2.4"


5. why 如何管理

1.应用的整体全局状态以对象的方式存放于单个 store
2.唯一改变状态树(state tree)的方法是创建 action
3.一个描述发生了什么的对象,并将其dispatchstore

  1. 要指定状态树如何响应 action 来进行更新,你可以编写纯reducer 函数,这些函数根据旧 stateaction来计算新 state

三大原则

  1. 单一数据源
    整个应用的state被存储在一棵object tree 中,并且这个object tree 中只存在唯一一个的store中.
  2. state是只读的
    唯一改变state的方式就是除非action,action是一个用于描述已发生事件的普通对象
  3. 使用纯函数来执行修改
    为了描述action 如何改变state tree,你需要编写纯的reducers

6. How 杂用

6.1 入口 index.js 配置

// redux存储器
import store from "./store"
// 注入store
import { Provider } from 'react-redux'
  <Provider store={store}>
     <App />
    </Provider>

6.2 配置解析

  1. store目录是自己新建的和 入口 index.js同级
  2. 新建store文件store/index.js ,当然名字你自己随便起叫store.js也行,这作为我们应用程序的单个store
  3. 引入Provider 对象 包裹起来我们的 App 应用程序组件
  4. 通过store属性全局注入我们的 store ,这个就是上面说的单个store

7. store配置

src/store/index.js

7.1 配置

import { createStore } from "redux";
let  defaultState = {
    counter:0
} 
function reducer(state=defaultState,action){}
let store = createStore(reducer)
export default store

7.2 vuex VS react-redux

 let store = createStore({
     state:{},
     mutations:{}
 }); 

观察下 vuex的配置 对比起来好理解


8. 配置解析----createStore

1.需要从 redux 引入创建函数 createStore
2.createStore 需要1个参数reducer


8.1 what reducer 啥玩意?

简单来说: 类似一个中间处理器 ,记录状态的改变

不简单的官方来说

reducer是一个函数,接收当前的state和一个 action对象,必要时决定如何更新状态,并返回新状态

函数语法是:(state, action) => newState。
你可以将reducer视为一个事件监听器,它根据接收到的 action(事件)类型处理事件。


8.2 Reducer 必需符合以下规则

1.仅使用 state 和 action 参数计算新的状态值
2.禁止直接修改 state。必须通过复制现有的 state 并对复制的值进行更改的方式来做 不可变更新(immutable updates)。

3.禁止任何异步逻辑、依赖随机值或导致其他“副作用”的代码
不能执行有副作用的操作,如API请求和路由跳转
不能调用非纯函数 如Date.now() Math.random()


9.reducer

需要状态配置信息参数(状态的初始值,以及修改状态的方法)
需要2个参数
第一个参数state: 需要管理的数据状态初值
第二个参数action:描述发生了什么


9.1 核心代码

let  defaultState = {
    counter:0
} 
function reducer(state=defaultState,action){
    switch (action.type){
        case "counter/incremented":{
            //  如果 state 是普通对象,永远不要修改它
            //  方式一
            let tempState = JSON.parse(JSON.stringify(state));
            tempState.counter += action.payload
            return tempState
        }
        case "counter/decremented":{
             return{
                 ...state,
                 counter:state.counter - action.payload
             }
        }
        default:{
            console.log("switch  默认")
            return state
        }
    }
}

9.2 action 概念

action 是一个具有type字段的普通 JavaScript 对象
描述应用程序中发生了什么的事件.
action类似vuex必须通过commit提交 mutations 根据类型来修改state


9.3 type 解析

1.mutations 通过commit提交的时候 其实也有个type类型

  1. react-reduxaction也有这个类型
    3.type字段是一个字符串,给这个action一个描述性的名字
    推荐type写法
    比如"counter/incremented"。我们通常把那个类型的字符串写成“域/事件名称”,
    其中第一部分是这个 action 所属的特征或类别
    第二部分是发生的具体事情

我们不能直接改变 state,如果直接改,会让数据流的变化不可预测

9.4 state 修改方式- -JSON

1.通过JSON 相关API 实现简易的深拷贝

  1. payload 载荷直接作为action的属性来接收参数,名字可以随便起
 case "counter/incremented":{
            //  方式一
            let tempState = JSON.parse(JSON.stringify(state));
            tempState.counter += action.payload
            return tempState
        }

9.5 state修改方式 --展开运算符

 case "counter/decremented":{
             return{
                 ...state,
                 counter:state.counter - action.payload
             }
        }

运用了 展开运算符
会覆盖掉之前的值


1.png

10. store梳理

1.Store 就是用来维持应用所有的state 树 的一个对象
2.改变 store内 state 的惟一途径是对它dispatch 一个 action。
3.Store不是类。它只是有几个方法的对象。 要创建它,只需要把根部的reducing 函数 传递给createStore
4.调用createStore的时候,reducer会被默认执行一次,完成对状态的初始化(执行里面的default)


11. 更新 state dispatch

11.1 基本概念

(Store): 保存了应用所有 state 的对象。

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


11.2 核心代码

store.dispatch({
    type:"counter/incremented",
    payload:10
})
store.dispatch({
    type:"counter/decremented",
    payload:5
})

type类型和 reducer 里面保持一致


11.3 dispatch 理解

dispatch 一个 action 可以形象的理解为 "触发一个事件"。
发生了一些事情,我们希望store 知道这件事。
Reducer就像事件监听器一样,当它们收到关注的 action 后,它就会更新 state `


12. 获取 state 状态

调用 getState() 可以获取新 state。

console.log("获取修改前store状态:",store.getState())

13. 监听 state 改变

也可以 通过subscribe监听 state的变化,然后更新 UI
监听 store.subscribe(()=>{}()
销毁 unsubscribe();

let unsubscribe = store.subscribe(()=>{
    n++;
    console.log("状态改了",n);
    // store.getState()
})
// 一般在组件销毁的时候使用 unmounted
unsubscribe();


14. 完整代码

能看到这里的,都是具备技术大牛的潜质,付上简易代码

import { createStore } from "redux";
/* redux的核心配置,中间处理器 ,记录状态的改变
let  defaultState = {
    counter:0
} 
// 需要状态配置信息参数(状态的初始值,以及修改状态的方法)
function reducer(state=defaultState,action){
    switch (action.type){
        case "counter/incremented":{
            //  state 永远不要修改它
            //  方式一
            let tempState = JSON.parse(JSON.stringify(state));
            tempState.counter += action.payload
            return tempState
        }
        case "counter/decremented":{
             return{
                 ...state,
                 counter:state.counter - action.payload
             }
        }
        default:{
            console.log("switch  默认")
            return state
        }
    }
}
//调用createStore的时候,reducer会被默认执行一次,完成对状态的初始化(执行里面的default)
let store = createStore(reducer)
export default store
/* 
vue这样写的 借鉴的就是redux
 let store = createStore({
     state:{},
     mutations:{}
 }); 

 */
// ************** 获取状态
console.log("获取修改前store状态:",store.getState())
var n = 0 ;
// 返回值就是销毁自己的方法
let unsubscribe = store.subscribe(()=>{
    n++;
    console.log("状态改了",n);
    // store.getState()
})
// 一般在组件销毁的时候使用 unmounted
unsubscribe();
//  修改状态
store.dispatch({
    type:"counter/incremented",
    payload:10
})
store.dispatch({
    type:"counter/decremented",
    payload:10
})


15. 数据流图示

redux.gif

16. 后记

梳理了 N遍,思维导图梳理,文章梳理,markdown梳理讲课步骤,代码也写了N多遍,我自己算是比较明白了
不知道讲的明不明白,大概看了下,可能文章太长了,现在焦虑的心理,可能对这种长文章顺手就关了,如果看到,希望对你有帮助


参考资料

redux基础
redux-实战
react-redux 基础
react-redux-reducer拆分
react-redux


初心

我所有的文章都只是基于入门,初步的了解;是自己的知识体系梳理;
如果能帮助到有缘人,非常的荣幸,一切为了部落的崛起;
共勉

相关文章

网友评论

    本文标题:轻松搞定 -react-redux-基本用法

    本文链接:https://www.haomeiwen.com/subject/borzmltx.html