React难点redux—H5逆战班
在学习React过程中,感觉React的redux比Vue的vuex更难上手。而react-redux便帮我这种小白省很多麻烦。这是根据学习的笔记做的一个简单的总结
react状态管理–react-redux
中文文档:https://www.redux.org.cn/
(1)react-redux有哪些内容?
我们已经知道,在vuex中包含了store , actions , states , mutations , getters , modules等几部分。
在react中,大致也包含相应几部分,如下:
- Action ---- 基本等价与vue中的action,代表了用户的行为
- Reducer —等价于vue中的mutations,用于返回变化之后的state,从而改变页面
- Store ---- 基本等价于vue中的store,存储所有的全局数据和行为
(2)redux模块安装与引入
cnpm install --save react-redux redux
import { createStore } from 'redux'
import { Provider, connect } from 'react-redux'
模块说明
① redux :主要用于创建Store对象,做状态管理
② react-redux:提供一些方式将redux绑定到react上(默认redux是独立的,可以使用在任何框架上,然后如果要在react中使用,就需要使用react-redux进行绑定)
(3)react-redux 的使用说明
要使用redux,主要就分为两个阶段:
第一个阶段是创建store对象,
第二个阶段是将store对象放入到组件中使用
---------阶段一:创建store对象-----------
1. 定义store中的数据(state)来源—action
1) vue中的state
在前面我们做vue开发时,store中的state我们是直接定义在store中的state选项里面的,然后还有另外几个选项:getters,mutations,actions,modules
2) react中的state
在react中的话,并没有什么state选项让你先把要使用的数据定义好,对于state状态数据,你需要使用action进行产生。
3) react中的action
react中的action和vue中的action在含义上大致一致,都代表了一种需要修改state的用户行为,并且都是使用dispatch进行触发
4)action对于store中的state作用
在react中,action是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store
//这里我为了管理用户名和用户成绩,所以定义了3个action,
//前两个action负责对成绩score进行加减,最后一个ation表示对用户名的修改
//他们将在store中产生state:score,UserName
var addScoreAction = {
type: "addScore",
data: 5,
}
var reduceScoreAction = {
type: "reduceScore",
data: 5,
}
var updateUserNameAction = {
type: "updateUserName",
newName: "李四",
}
2.定义store中的state构造器—reducer函数
刚才我们知道了,store中的数据来源是action。但是有了action后,state具体是如何通过action产生的呢?
这时我们就需要明白reducer函数了
reducer作用:
在react中,有了action后,我们通过dispatch进行派发action,并不是直接派发到store对象上的,而是派发到reducer函数上,然后reducer函数经过一些运算产生真正的state注入到store中。
所以,有了action这个state的唯一来源后,我们还需要定义reducer,他将接受dispatch派发而来的action。
//由于上面的三个action主要产生了userName和score两个state,所以我们需要定义两个reducer
// reducer是为了根据action产生state的,他将接受两个参数:分别他对应的state和传来的action
function scoreReducer(scoreState = 60, action) {//设置state的初始值60
switch (action.type) {//根据用户发来的action,在case下做逻辑运行,然后返回新的的state
case "addScore":
return {
score: scoreState + action.data
}
case "reduceScore":
return {
score: scoreState - action.data
}
default:
return { score: scoreState }
}
}
//接收修改用户名名的action
function updateUserNameReducer(userNameState = "张三", action) {
switch (action.type) {
case "updateUserName":
return {
userName: action.newName
}
default:
return { userName: userNameState }
}
}
3.把reducer产生的state正式放入到store中—createStore
定义的reducer将会根据action产生我们需要的state,然后即便是在没有action时也会有一个初始化的state,使用createStore创建一个store对象,并强行将reducer产生的state注入进store对象里面
第一步:将所有的reducer合并,即把每个reducer参数的state合并
第二步:将合并后的reducer传入到createStore当中
//将所有的reducer合并在一起,然后初始的state可以为空,因为每个子reducer都是给了初始值的
function allReducer(state = {}, action) {
return {
//因为每个reducer返回的都是对象,所有需要展开一下
...updateUserNameReducer(state.userName, action),
...scoreReducer(state.score, action),
}
}
---------阶段二:使用store对象-----------
1.将store中的state放入到组件中使用–map辅助函数
辅助函数如下:
- mapStateToProps:将state映射到props上
- mapDispatchToProps:dispatch映射到props上(分发action到reducer,使state改变)
2.使用Provider 向辅助函数传递store中的state
map函数需要state才能完成映射,所以我们需要在根组件的外面包裹容器组件Provider向辅助函数传入store中的state
ReactDOM.render(
<Provider store={store}>
<Index />
</Provider>,
document.getElementById('root')
);
3.在组件中具体使用–this.props.xxx
映射之后,组件里面将可以通过this.props获取到store中传来的内容
<div className="App">
用户:{this.props.userName} <br/>
成绩: {this.props.score}<br/>
<button onClick={this.props.updateUserName}>修改用户名</button>
<button onClick={this.props.addScore}>成绩+</button>
<button onClick={this.props.reduceScore}>成绩-</button>
</div>