React-Redux 状态管理详解:核心概念与实战应用
June 17, 2025 (7mo ago)
react-redux状态管理,类似于vuex,这个是在redux中非常重要的一点!
redux是js的状态容器,和vuex差不多
redux可以构建,一致性的应用,原生的可以,而且也可以兼容更多的库jq也可以 原生的js也可以使用
redux很小只有2kb
设计的初衷,数据越来越复杂,嵌套的数据太多,管理不断变化的state非常的麻烦,那么我们就需要一个全局的容器
来管理这些状态,避免混乱
三大核心概述
- 单一状态树,
这一点都和vuex的概念是一样的,整个的页面的state都会存在一颗object tree中,而object tree又存储在
soter中
- state是只读的,
和vuex中的muation是一毛一样的,只不过变成了另一个名字 action,
改变state的唯一方法是触发一个action,action就是一个普通的对象,所有的修改都会集中处理,并且一个一个的
去执行
如何发送一个acion?非常的简单 和vuex中也差不多 
- 使用纯函数,来执行修改
为了描述action如何改变state tree,你需要去编写reducers,
reducers,是一个纯函数而已啦,它接受先前的state和action 返回新的state,
它可以复用,控制顺序,传入辅助参数
redux的核心组成
State-状态
这个就是我们传入的数据,我们在做react的时候,大概可以分三类state

Action-事件
这个实际上action就是一个对象,它是一个载体
特点如下:
注意啊,action是描述,表示将要有什么改变

reducer
这个东西也算是一个函数,响应传递过来的actions,然后处理它,最终把处理好的state发送会store

Store核心

小结

示例小demo
首先是起项目
一个非常简单的基于reatc-creat-cli的小项目需要启动出来,让后初始化删除一些没有用的东西,配置一下我们的目录,下载redux就好了
- 重点说明:我们需要删除那些不需要的文件呢?
我们只需要保留如下的文件就好了
其它的初始化的时候一些没有用的都可以删除掉
最后就是你需要安装redux就好了
大概的步骤如下



代码层级如下

- 核心代码如下
/action
/**
* action 构建函数
*/
const sendAction = () => {
return {
type: 'SEND_TYPE',
valu: '我是一个action'
}
}
export { sendAction }/reducer
/**
* 本文件用来创建reducer函数来处理传递过来的acstion
*/
const initState = {
value: '默认的值'
}
const reducer = (state = initState, action) => {
switch (action.type) {
case value:
return Object.assign({}, state, action)
default:
return state
}
}
export { reducer }/store
import { createStore } from 'redux'
import { reducer } from '../reducer/index'
/**
* 构建 传入参数,构建store
*/
const store = createStore(reducer)
export { store }/page
import React from 'react'
import { sendAction } from '../action';
import { store } from '../store';
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
handClick = () => {
const action = sendAction()
// 发送action
store.dispatch(action)
}
// 监听
componentDidMount () {
store.subsctibe(() => {
// 注意要触发redner需要重新调用setdata
this.setState({})
})
}
render () {
return (
<>
<button onClick={this.handClick}>点击我,发送一个action</button>
<div>{store.getState().value}</div>
</>
)
}
}
export default Home;react-redux
在上面的代码我们知道了这样的一个事情:如果我们需要频繁的搞这个redux那么,是非常麻烦的,我们有没有一个东西,可以全局的管理这些storte呢?这个就是我们的react-redux的作用
概述


有两个非常重要的东西,需要我们学习,

- provider是什么?它的原理是什么?

- connect

- 总结

基础的使用
我们需要实现如下的这个小的功能

首先是前期的准备工作
- 首先 下包
npm install react-redux
npm install redux
# 注意啊,我们的react-redux是依赖redux的,所以你需要把redux也下载下来- 其次是构建文件目录

- 然后是写代码(这里的代码及仅仅是我们的reducer还有页面的结构还有我们的stroe)
这里我们书写了 page两个页面,还有一个人reducer 还有srtore东西
/Com A 和B的组件


我们来看一下核心的几个代码
/reducer

/store

使用provider来包裹数据
这个是一个组件!!!,它的作用就想之前我们的转态提升的provider东西一样
- 在我们的provider组件包裹组件结构,达到统一维护store的目的
app.js

注意啊,这里的这个语法还有proiver接受的参数的固定的语法
有了提供者,我们还需要消费者
这个消费者就是connect,connect放回一个加强之后的组件HOC
注意啊这里的语法,实际上是内部的处理是一个HOC模式,它在HOC封装了一下把全局得我store数据床底到了组件内部的prop上,这种设计就非常的巧妙
- 参数项说明

在官方文档上比较难理解,我们在项目中就非常容易的理解了
- 这个map和vue上的东西也非常的类似
- 组件A是发送方,需要实现第二个参数
思路:


我们还需要方法去触发它。于是就有了hannClik

重点说明:我们的ruderver第一次进来的时候,我们的react第一次底层上会进行触发的,第二次来的时候会与第一次的值进行比较如果没有变哈,那么react底层上不会执行的,如何解决这个问题呢?你需要使用object.assing( {},state,action ) 就好了,返回新的state,这样就能欺骗react底层了
- 我们的B组件需要接受数据,
思路:

- 在我们的redux中初始化值,这个还是非常关键的,初始化值

- 在组件上
细节说明,如果你的connect回自动给你生成第二个参数

正式的进入逻辑
reudcer,js中才是我们正在的逻辑代码所在

这个案例中数据的扭转?😋

非常重要,非常通用的设计模式
自己的个人理解,action是一个载体表示将要做什么,reducer是接受action参数,处理一些数据,数reducer是数据的更改初始化的地方,store是管理实现rudeux和compensation通信的容器
combineReducers
概述和介绍
我们的之前写的代码仅仅是一个reducer,如果项目非常的大,你只有一个reducer完成起来就会非常的麻烦,因此这个东西就出来了,它可以管理多个reducer

语法是非常的简单
combineReducers是一个函数 返回组合之后的总的大的,reducer
const reducers = {
home:HomeReducer,
login:LoginReducer,
}
exprot combineReducers( reducers )
案例时间到了
我们将会学习到如下的知识点

我们需要完成这样的一个需求
两个组件,这两个组件有各自的按钮,点击的时候,可以通过redux获取到各自对应reducer的数据,而不是一个reducer数据,现在我们希望使使用combineRuducers来改造它。
案例准备 (没用使用combineRuducers的时候)

代码如下
项目的目录结构

// 注意啊 ,现在我们的一个组件需要
./comA
import React from 'react';
import { connet } from 'react-redux'
class ComA extends React.Component {
constructor(props) {
super(props);
}
handerClick = () => {
this.props.getUser()
}
render () {
return (
<>
<button onClick={handerClick}>点击我获取用户数据</button>
<ul>
<li>姓名:{}</li>
<li>邮箱:{}</li>
</ul>
</>
);
}
}
mapStateToProps = (state) => {
return state
}
mapDispatchToProps = (dispatch) => {
return {
getUser = () => {
dispatch({
type: 'GET_USER'
})
}
}
}
export default connet(mapStateToProps, mapDispatchToProps)(ComA);
/comB是与A类似的,这里就不写了
/sotre/reducers/index
const ininSatte = {}
export function rootReducer (state = ininSatte, action) {
return Object.assign({}, state, action)
}
/sotre/index.js
import { createStore } from 'redux'
import { rootRoducer } from '../store/reducer'
export default createStore(rootRoducer)
/App
app这里非常的简单这里就没有写了,app上直接包裹上一个proders就好了
在rooteRedux中对action进行统一的处理
我们定义了一些数据,在一个reducer里的代码

对我们的这个rootReducer进行一个改造

对我们的这个ComA还有ComB进行一个改造

使用combine进行拆分

这里只给出了最核心的几个代码
- 首先是我们的改造的文件夹目录结构,这里就详细的说明了,实际上就改了文件夹的组织方式,和新命名了这个文件
然后是我们的这个该改造之后的两个子reducer
UserReducer

另一个也是是一样的

- 然后是我们的引入
/store/index.js

- 注意啊我们使用的时候也需要经过一般改造

具体的组件内的使用

特点说明

\\第二个特点

第三个特点 重要!


综合案例,书城
这个案例业务逻辑稍微有些复杂,但是本质上还是一样的套路,本人在b站找了一些不错的资源
核心思路如下

分步骤的案例如下


redux-saga(处理异步)
官方API,请自行服用,saga
简介
- 中间件

总结一句哈,我们可以用中间件,拦截一下action ,再把action 放出去
- sage的核心,辅助函数 + effect

Sage相关的api介绍
这一讲,主要是将的是如何进行与store的关联
/sage/index

注意啊。一步仅仅是建立了联系,但是在我们的自己建立的sage/index.js下没有什么代码。所以你,就算你在组件发送了dispatch也是不会有什么效果的,因为没有在saga中 监听
saga的辅助函数的说明
以下的是东西 ,是一个简单的saga函数的说明项,官方的文档比较晦涩难懂,我们还是根据代码的来看具体的作用是什么

组价的触发事件,这个和我们我们之前写的都是一毛一样的,没有什么不同直接发action就好了

在我们的store/sage/index.js中进行监听,注意啊这里的es6的新特点 yield函数

三个辅助函数的说明
我们来请求接口,看看具体的区别是什么。这里我们直接写在sage中,进行了一些拦截处理还有辅助函数的使用

这三个辅助函数的区别是什么?

Effect函数

这里有必要说一下take的东西,take就是run的时候就堵塞,匹配到之后就接着进行

- 发送action就能发送出去action

reducer中如何接受到了呢?,注意啊这约定俗成,我们的这object.assgina是最约定俗成的方法

总结

项目实战
初始化项目准备action, reducer,分模块的saga
学以致用,我们来完成一个项目的实战吧!案例描述,我们来实现一个异步网络请求的在线书城项目
注意啊,这里实际上还有我们的reducer我们还没有写,你需要自己写一下
我们的aciton类型常量也需要自己设置一下
这两个reducer中写的东西和我们之前写的东西是一毛一样的,没有任何的变化,我们的变化只是集中在saga文件中拦截做对应的处理
要点就是同时运行两个saga这个是一个要点
/saga/index.

/sore/index/js。进行我们的数据管理

实现登录
- 思路的讲解

- 重点说明
- 登录的saga 处理逻辑

- 登录的rudecer如何拿到数据之后如何处理

- 前台的触发条件
我们的map把redux中的store进行映射到了当前组件的props上,如果有请求就说明prop变了,那么我们就需要在组件的内部进行一定更新处理

后续的操作就是进行业务的处理,这里就不详细的展开了
书籍的列表数据
思路都是一样的,这里就不展示源代码了
- 组件的加载的时候直接触发钩子函数,发送action请求数据

- 在saga中进行监听action,并且请求数据

- 最后你需要put一下把获取到的数据丢出去
4
- 在reducer里,进行数据的放回

- 在相对应的组件页面进行数据处理就好了

注意啊,这里解释一下,为什么这里不需要直接赋值,因为我们在redern函数中,页面第一次的时候就直接解构加载a了





