React Redux基本使用

参考资料:

https://juejin.cn/post/6844903846666321934#heading-5

https://juejin.cn/post/6926509360596123661#heading-1

1. redux

React有props和state:

  • props意味着父级分发下来的属性
  • state意味着组件内部可以自行管理的状态,并且整个React没有数据向上回溯的能力,这就是react的单向数据流

这就意味着如果是一个数据状态非常复杂的应用,更多的时候发现React根本无法让两个组件互相交流,使用对方的数据,react的通过层级传递数据的这种方法是非常难受的,

在项目,我们往往会有这样的需求,根据当前登录的用户的信息展示不同的菜单或者数据,这就需要我们在任意组件中能获取到登录用户的信息,要怎么做呢?如果没有这些框架,我们肯定会想办法将这些全局的信息统一存储到一个地方,设计好对应的数据结构存在一个 js 对象中,并且这个对象必须 单例 的,保证每次获取的数据都是同一个。对于修改逻辑,也要遵循既定的规则,保证每次数据修改都是可追溯的。如果没有这些规则的约定,那么状态(数据)的修改变得混沌无序,代码变得乱七八糟,系统潜在的问题增多。

这个时候,迫切需要一个机制,把所有的state集中到组件顶部,能够灵活的将所有state各取所需的分发给所有的组件,是的,这就是redux

(1)redux机制介绍

在这里插入图片描述

  • actions

    函数形式,返回 action 对象,通常具有type属性。负责指令的生成,页面通过 store.dispatch(action) 向 store 发送数据修改的请求。

  • reducers

    一个纯函数,接收两个参数 (previousState, action) 第一个表示修改之前的 state 的值,action 是上一步页面通过 store.dispatch(action) 向 store 传递的 action。
    reducers 通过 action 的 type 的值进行不同的处理,返回一个新的变量 newState。reducers不能直接修改传递进来的 previousState.

  • store

通过 const store = createStore(reducer); 创建一个 store 对象。
需要导入到 React 组件文件中,通过 this.state = store.getState(); 让组件获取 store 中的数据;

整个过程就是 redux 的三大原则:

  • 单一数据源: store 中数据是单例,全局唯一的。
  • State 是只读的: 唯一改变 state 的方法就是触发 action, store.dispatch(action); 直接修改 state 是不起作用的。
  • reducers 是纯函数 保证在(previousState, action)确定的前提下,多次执行的结果是一样的;并且不直接修改 state ,通过 Store 触发 state 的修改。

(2)基本使用

  1. 创建reducer

    可以使用单独的一个reducer,也可以将多个reducer合并为一个reducer,即:combineReducers()
    action发出命令后将state放入reucer加工函数中,返回新的state,对state进行加工处理

  2. 创建action

    用户是接触不到state的,只能有view触发,所以,这个action可以理解为指令,需要发出多少动作就有多少指令action是一个对象,必须有一个叫type的参数,定义action类型

  3. 创建的store,使用createStore方法

    store 可以理解为有多个加工机器的总工厂
    提供subscribe,dispatch,getState这些方法。

2. react-redux

react-redux 是将 react 和 redux 结合,其核心思想和机制依然不变

(1)设置action和actionType

aciton负责定义行为并且派发改变的数据和行为给store,store通过store.dispatch再发给reducer,reducer进行行为识别和数据的接收

这里我们将actionType和aciton进行统一管理。

actionType.js:
在这里插入图片描述
aciton.js
在这里插入图片描述
type表示当前action目的是用来做什么的,以此来区分不同的改变store数据的行为(比如增加money金额)

data表示需要目标aciton行为需要携带的参数或者说是需要修改的具体数值(比如增加500块的money金额)

(2)设置reducer

reducer负责根据指定action的区分来对指定的state进行处理。

一般来说每一个reducer都是一个纯函数,代表一种state数据。其默认有两个参数(当前state的值,传过来的action)。

你也可以只需要一个reducer函数来处理所有的aciton,此时的state应该是个存储所有State的对象。每次只更新对象中指定的state

其中当前state一般会赋值一个初始默认值,然后后续每次的更新都会基于preState的值进行处理,并返回一个逻辑处理后的newState值。然后交给store进行对应state更新

reducer.js
在这里插入图片描述

(3)创建store并注入全局

只有store才是负责更新state的,并且reducer必须是个纯函数;reducer负责进行处理逻辑并返回一个newstate给store,然后store再进行自我更新;

store必须是唯一的,不允许存在多个store

store.js

在这里插入图片描述
将store.js暴露出去后,传给顶层组件App.js的props后,在顶层组件内部,引入react-redux的Provider并传入prop store

App.js(顶层组件)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bW9jIvly-1622874605459)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6627006014394cc8a5cc030116978064~tplv-k3u1fbpfcp-zoom-1.image)]

(4) 在组件中使用Store的数据和更新Store数据

需要用到以下三个函数:

  • mapStateToProps 函数,将 store 中的 state 转为组件的 props
  • mapDispatchToProps 函数, 传入 dispatch 用于触发 action。
  • connect 函数(本质上对应的是redux的Store.subscribe)。
const mapStateToProps = (state)=>({
    inputValue: state.inputValue,
    list: state.list
})

const mapDispatchToProps = (dispatch) => ({
    hanldeAdd: ()=>{
        dispatch(addItem());
    },
    changeInputValue:  (e)=>{
        dispatch(changeValue(e.target.value));
    },
    deleteItem: (key)=>{
        dispatch(deleteItem(key))
    }
})
// 接收 mapStateToProps 和 mapDispatchToProps 两个参数,
//并返回一个函数,这个函数接受 TodoList 返回一个封装的组件。
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);

在这里插入图片描述
(5) redux-thunk(异步中间件)

如果按照原始的redux工作流程,当组件中产生一个action后会直接触发reducer修改state,reducer又是一个纯函数,也就是不能再reducer中进行异步操作;

而往往实际中,组件中发生的action后,在进入reducer之前需要完成一个异步任务,比如发送ajax请求后拿到数据后,再进入reducer,显然原生的redux是不支持这种操作的

redux提供了redux-thunk这个中间件可以让我们actions 和 reducers 之间 “ 动一些手脚 ”,先处理异步的请求,再去触发 dispatch 向 store 发起操作。

在store中加入中间件redux-thunk:

import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import reducer from "../reducers";

const store = createStore(reducer, applyMiddleware(thunk));

export default store;

在某个aciton中使用异步:

// actionCreator.js
export const getInitList = ()=> {
    return function(dispatch){
        axios.get("/api/initList.json").then(res=>{
            dispatch(initList(res.data))
        })
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值