React中使用Redux
redux是什么?
redux是状态管理及更新工具,通过派发action来改变状态,使用redux可以使编写的代码可预测可测试,确保代码是按照我们预期的方向执行的。
redux构成
redux是由以下几部分构成
state : 应用真实数据源
view : 应用当前状态UI
action : 根据用户操作的事件改变state状态并更新
单向数据流
state用于描述特定时间点状态
基于state渲染出来View
用户出发事件,state根据state产生新的state
不可变性
数组是可变的,例如
let obj = { name: '张三', age: 18 }
// 改变对象内的name
obj.name = '李四'
// 同样的,下面的数组的内容改变了
let arr = ['a', 'b']
arr.push('c')
arr[1] = 'd'
但是state是不可变的,这就使得我们不能像数组一样,这样改变了原有数组 如果不想改变原有数组,我们必须复制一份原有数组出来,然后更新复制出来的数组
const obj = {
a: {
// 为了安全的更新 obj.a.c,需要先复制一份
c: 3
},
b: 2
}
const obj2 = {
// obj 的备份
...obj,
// 覆盖 a
a: {
// obj.a 的备份
...obj.a,
// 覆盖 c
c: 42
}
}
const arr = ['a', 'b']
// 创建 arr 的备份,并把 c 拼接到最后。
const arr2 = arr.concat('c')
// 或者,可以对原来的数组创建复制体
const arr3 = arr.slice()
// 修改复制体
arr3.push('c')
这就是不可变性,state可以改变复制拷贝出来的state,但事实不可以改变原有的state
创建redux以及异步处理saga(做一个简单的计数器)--->先做同步在做异步便于理解
先创建一个react应用
npx create-react-app rduxsaga
1.安装redux react-redux redux-saga
npm install redux react-redux redux-saga -S
2.创建store仓库以及index.js、action.js、actionType.js 、reducer.js
actionType.js中创建一个变量(action状态)
export const ADD = 'ADD';
reducer.js中引入actionType.js对传入的action状态做比较
import * as actionType from './actiopType';
const reducer = (state = { number: 0 }, action) => {
switch (action.type) {
case actionType.ADD:
return { number: state.number + 1 };
default:
return state;
}
};
export default reducer;
再index.js中引入reducer.js和actionType.js并用createStore创建store传入reducer
//创建store createStore reducer actionType
//引入createStore
import { createStore } from 'redux';
//引入reducer并传入
import reducer from './reducer';
let store = createStore(reducer);
//导出store
export default store;
/**
* store
* ={
* getState 获取最新状态
* subscribe 实现状态变更的订阅
* dispatch 向仓库派发最新的动作
* }
*/
3.前期的仓库准备大致完成了,接下来再最外层的入口文件index.js中使用store
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
//引入store传入下去
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
4.还要创建一个actions.js,便于统一调用action按批发的方法
//引入actionType
import * as actionType from './actiopType';
const actions = {
add() {
//返回一个action
return { type: actionType.ADD };
},
};
export default actions;
5.开始App.js的使用(详细信息都已标记注释)
import React, { Component } from 'react';
import actions from './store/action';
//引入connect来连接仓库
import { connect } from 'react-redux';
class App extends Component {
render() {
return (
<div>
{/* 这里的this.props.number拿到的是state */}
<p>{this.props.number}</p>
{/* 这里的this.props.add 拿到的是reducer*/}
<button onClick={this.props.add}>+</button>
</div>
);
}
}
let mapStateToProps = (state) => state;
//connect中传入connect属性一次 在执行一次所以有两个()
//传入的组件有
export default connect(
mapStateToProps, //把仓库状态映射为组件属性,把组件状态变成组件的props,上面就可以通过this.props拿到仓库的状态----->可以拿到state
actions //action也会成为组件的书属性 -------->可以拿到reducer
)(App);
/**
* 组件连接store仓库
* 输入 把组件中的状态输入到组件中来 也就是读取仓库中的state状态
* 输出 把组件的状态输出到仓库中去 在仓库中写入状态
*/
6.运行一下,一个同步的store仓库已经可以了,实现了同步的计数器