项目场景:
在实际的开发过程中,我们时常会遇到这样一个问题,当我们的父子组件以及多个组件同时共用一个数据时,我们如果仅用父子间传数据,页面间传数据,就会使得代码非常的冗余,另外也会加大代码量,因此我们使用redux进行数据管理(建议能不用就尽量不用)
什么是redux:
“Redux 是 JavaScript 状态容器,提供可预测化的状态管理”
Redux 的设计思想很简单,就两句话:
1.Web 应用是一个状态机,视图与状态是一一对应的。
2.所有的状态,保存在一个对象里面。
redux有三大准则
1.单一数据源
整个应用状态,都应该被存储在单一store的对象树中。
2.只读状态
唯一可以修改状态的方式,就是发送(dispatch)一个动作(Action),通俗来讲,就是说只有getter,没有setter。
3.使用纯函数去修改状态,(纯函数是指 不依赖于且不改变它作用域之外的变量状态 的函数,也就是说, 纯函数的返回值只由它调用时的参数决定 ,它的执行不依赖于系统的状态(比如:何时、何处调用它)
redux同步操作:
首先在使用redux之前,必须安装和引入redux
redux安装
cnpm install redux --save
安装完成之后,我们需要引入redux并创建store
store.js内容
import {createStore} from 'redux'//引入redux
let add=(state,number)=>{
return state+number
}//定义加法运算函数
//定义reducer函数,state=0,是为了在一开始调用容器时为state赋初值
var reducer =function count(state=0,action){
console.log(state,action);
//通过action.type选择对state进行的操作
switch (action.type) {
case 'add':
return add(state,action.content.number)
default:
return state
}
}
//创建store,store是容器,参数reducer实际是一个函数,用来管理数据
const store=createStore(reducer)
//将容器暴露
export default store
admin.js内容
//引入react
import React, { Component } from 'react';
//引入store
import store from './redux/store'
//创建admin组件
class Admin extends Component {
//构造函数
constructor(props){
super(props)
//使用store.getState()获取当前的state
this.state={
count:store.getState()}
}
change=()=>{
//dispatch为需要对state进行操作时调用,传入一个对象包含action和content
store.dispatch({type:'add',content:{number:2}})
console.log(store.getState());
}
render() {
{/*使用store.subscribe()在store中state的值进行变化时调用*/}
store.subscribe(()=>{this.setState({
count:store.getState()
})})
return (
<div >
{this.state.count}
<button onClick={this.change}>123</button>
</div>
);//点击按钮count+2
}
}
export default Admin;
这样就可以实现按钮点击加二
redux异步操作::
redux实际是不支持异步操作的,如果要进行异步操作,就必须要下载中间件
下载中间件
npm install --save redux-thunk
store中引入中间件
import {createStore,applyMiddleware} from 'redux'
//引入中间件
import thunk from 'redux-thunk'
//创建store时。必须传入reducer,reducer由我们自己定义
//store对象内部管理新状态数据,状态数据的初始值为reducer()返回值,也就是说在最开始创建store是就会调用reducer()得到初始值
//reducer是真正管理状态的函数,可以对数据进行操作
//如果要对redux进行异步操作,必须要下载异步中间件,npm install --save redux-thunk
//异步action是一个函数,而且参数是dispatch(1),执行异步代码(2).完成后,分发一个dispatch函数
let add=(state,number)=>{
return state+number
}
var reducer =function count(state=0,action){
console.log(state,action);
switch (action.type) {
case 'add':
return add(state,action.content.number)
default:
return state
}
}
//异步action是一个函数,而且参数是dispatch(1),执行异步代码(2).完成后,分发一个dispatch函数。可以理解为异步过程完成后触发同步过程
//应用异步中间件
export var addasync=(number)=>{
return dispatch=>{
//(1),执行异步代码
setTimeout(() => {
//2).完成后,分发一个dispatch函数
dispatch({type:'add',content:{number}})
}, 1000);
}
}
//参数二为中间件
const store=createStore(reducer,applyMiddleware(thunk))
export default store
admin.js
import React, { Component } from 'react';
//引入异步函数
import store ,{addasync} from './redux/store'
class Admin extends Component {
constructor(props){
super(props)
this.state={
count:store.getState()}
}
change1=()=>{
//触发异步redux,可以理解为 store.dispatch(addasync(2)),触发的是addsync的返回值,是一个计时器,在计时器中回调了dispatch
store.dispatch(addasync(2))
console.log(store.getState());
}
render() {
store.subscribe(()=>{this.setState({
count:store.getState()
})})
return (
<div >
{this.state.count}
<button onClick={this.change}>123</button>
<button onClick={this.change1}>456</button>
</div>
);
}
}
export default Admin;
这样就可以看到,点击456,一秒后count+2