0.写在前面
很遗憾,最终还是没能入围2023年的博客评选。
不过不管怎么说,今年需要开个好头。
迫于成本压力吧,最终还是没能顺利离开这里。。。。。。
其实白天已经能放的下啦,我给自己买了喜欢的玩具,去了喜欢的漫展,做自己喜欢的orm开发。
只是在晚上的时候,心如乱码,睡不着,流泪。
1.什么是redux
redux是一种常用的状态管理组件,虽然redux被归类为react的全家桶中,但是实际上这个东西不仅仅支持react,而是全面适配js的。
但是我们仍然可以以react的情况作为一个案例分析,在react中,每个模块/组件,都维护了自己的state状态,里面是一些数值或者一些需要保存的东西。但是这带来一个问题就是,我们跨组件调用和维护显得异常麻烦。
而redux等状态管理工具,负责维护的是一个全局的状态组件,通过store对象来进行对于全局state的监听,修改,和获取操作。其实对标的是vue全家桶中的vuex。
2.redux的基本定义和概念
在了解redux之前,我们可以介绍一下如下四个概念:
action:顾名思义,动作,这个动作是一个对象,数值为state将要修改的数值。
在store内部的reducer函数中,我们可以根据传入的action修改state
需要注意的一点是,我们通常约定,action对象内部必须有一个字段type,既是方便了我们在reducer中识别的规范,也约定了这是一个action对象。
state:状态(注意action和state不能画等号,也并非一定要把action给转化为state,action仅仅只是指明了reducer如何修改state)
store:存储对象,也可以称之为状态管理对象,用来保存state,并且提供一些state的操作。
reducer:一个用来处理action的函数,根据reducer可以生成一个store对象,根据redux的要求,reducer需要接受两个参数,state和action,返回根据逻辑修改以后的state. 简单来说reducer就规定了store在接受到action以后,该进行怎么样的逻辑
大致的工作过程就是:
根据reducer生成store,再调用store对应的方法(比如使用dispatch提交action)
3.redux的构建和使用:
首先要先下载
npm install redux
下载完成以后,我们首先构建一个reducer对象
const rootReducer=(state={type:'',num:0},action)=>{
//内部执行逻辑
return action;
}
export default rootReducer;
然后根据reducer对象,构建一个store 对象
import {createStore} from 'redux' //被废弃了??
import rootReducer from './Reducer'
const store=createStore(rootReducer);//根据reducer策略实现store
export default store;
而对于action,我们通常做的方法是创建一个action构建方法,这是在实际工程中常用的方法
const sendAction=()=>{
return {
type:'这个东西干啥的',
num:1
}
}
export default sendAction;
接下来,在实际项目中,我们可以通过调用store的三个api来完成监听状态变化,提交变化,获取数值三个功能
根据创建的逻辑差不多是这样子的,首先要创建出一个reducer函数,这个函数接收两个参数,原本的state,以及全新传入的action
store对象内部根据全新的action,以及依赖构建的reducer函数,进行自己的逻辑判断,决定状态如何书写,最终返回一个新的state
Store对象有三个函数,分别为getState(), subscribe(), dispatch(),实现这些功能;
另外这里需要补充一个api:combineReducer
这个函数主要的目的在于,我们可能有多个处理逻辑,也就是有多个reducer。
还是很抽象,我说个例子
比如我们的状态中有两条:用户,计数器
假设这是一个很复杂的东西,我们需要拆分成多个reducer来处理
我们可以创建出两个reducer,分别用来修改这个两个东西,然后通过该api将两个reducer组合到一起。这样两个reducer生成的state将会组合成最终的state
代码如下
import { combineReducers } from 'redux';
// 子 reducer 1
function counterReducer(state = 0, action) {
switch(action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
// 子 reducer 2
function userReducer(state = null, action) {
switch(action.type) {
case 'SET_USER':
return action.payload;
case 'CLEAR_USER':
return null;
default:
return state;
}
}
// 合并 reducer
const rootReducer = combineReducers({
counter: counterReducer,
user: userReducer
});
// 创建 Redux store
const store = createStore(rootReducer);
4.react-redux:
redux可以直接使用在react中,但是redux也推出了react的官方适配版本,作出的改进主要有两个
1. 提供了更简单的store调用方法,不需要在每个模块里进行导包
2. 对组建进行增强,将发送action的方法和state中的属性全都绑定在props中
以上两个要点都是基于context机制实现的
操作方法如下:
首先store仍然是需要我们自己使用reducer构建出来的,和上面没有区别
(1)Provider,包裹根组件,保证store能传递到下方的任意组件
首先要创建一个provider,包裹跟组建,然后将我们的store对象传递下去
(2)创建mapDispatchToProps,mapStateToProps方法并且增强组件
import { useEffect } from "react"
import { connect } from "react-redux"
import store from "../../reactredux/store"
//使用了两个函数来实现了监听和修改的非手动操作
//两个函数分别返回封装成对象的Action构建方法,和新的state
//使用connect实现了,将新增Action的方法加入props,并且让这个方法在创建Action以后直接发送出去
//并且将state中的属性也给保存进props里面了
const mapStateToProps=(state)=>{ //返回值为新的state
console.log("修正以后的数据为",state) //将state中的属性放置在props中
return state
}
const mapDispatchToProps=(dispatch)=>{ //返回值为封装成对象的Action发送方法,这是一种推荐的做法
return{
sentAction:()=>{ //将这个对象内部的方法给绑定到props中
dispatch({ type:'', num:1})
}
}
}
//具体的使用
function Page2(props) {
const handleClick=()=>{
props.sentAction() //发送dispatch进行修改
}
return (
<div>
{props.type} //读取数据
<button onClick={handleClick}> ceshi1 </button>
</div>
);
}
//增强组件
export default connect(mapStateToProps,mapDispatchToProps)(Page2);