全局有一个公共的容器(所有组件都可以操作),我们可以在某个组件中把全局容器中的信息进行修改,而只要全局信息修改,就可以通知所有用到该信息的组件重新渲染(类似于发布订阅)==》redux就是这种解决方案:redux只有一个作用,就是为了实现组件之间的信息交互。
1.执行createStore
2.基于store.getState可以获取容器中存储的状态信息(拿到状态信息就可以做数据绑定等操作了)
3.我们可以基于store.subscribe向事件池中追加方法(也可以移除事件池中的方法)
4.修改容器中的状态信息
公共状态信息都是reducer去改的,reducer记录了所有修改状态的行为方式,我们以后想要知道怎么改的状态,只要看reducer即可。
画一张简易流程图
App.js
import {createStore} from 'redux'
/**
* 创建redux容器用力啊管理公共的状态信息
* 1.创建容器的时候其实已经准备好了管理员reducer了
* 2.createStore(reducer):相当于创建一个容器并雇佣了一个管理员reducer
* 3.创建出来的store存在几个属性:getState/dispatch/subscribe
*/
let store = createStore(reducer);
window.store = store; //把创建的容器挂载到全局下,保证每一个子组件都可以获取到store,从而执行一些其它的操作(当然也可以基于属性)
//reducer管理员是一个方法:reducer方法是在dispatch派发的时候执行的
//state:现有store容器中的状态信息(如果store中没有,我们给一个初始值)
//action: 告诉reduce如何去修改状态都在action中(它是一个对象,对象中固定的有type属性:派发任务的行为标识,reducer就是根据不同的行为标识来修改状态信息的)
function reducer(state = {
n: 0,
m: 0
}, action) {
//reducer就是根据不同的行为标识来修改状态信息的
switch (action.type) {
case 'support': state.n = state.n+1;break;
case 'against': state.m = state.m+1;break;
}
return state; //return的是什么,就会把store中的状态改成什么
}
<Vote></Vote> //调用
vote.js
import React from 'react';
import VoteHeader from './voteHeader.js'
import VoteBody from './voteBody.js'
import VoteFooter from './voteFooter.js'
class Vote extends React.Component{
constructor(){
super()
}
render() {
return (
<div>
<VoteBody></VoteBody>
<VoteFooter></VoteFooter>
</div>
)
}
}
export default Vote;
voteBody.js
import React from 'react';
class VoteBody extends React.Component{
constructor(){
super()
}
componentDidMount() {
//通过subscribe追加事件,进行强制更新
window.store.subscribe(()=>{
this.forceUpdate();
})
}
render() {
//获取状态的改变
let {n, m} = window.store.getState();
return (
<div>
<div>赞成{n}票</div>
<div>反对{m}票</div>
</div>
)
}
}
export default VoteBody;
voteFooter.js
import React from 'react';
class VoteFooter extends React.Component{
constructor(){
super()
}
render() {
let store = window.store;
return (
<div>
//通过dispatch通知reducer根据不同的标示修改不同的状态
<button onClick={e => store.dispatch({type: 'support'})}>赞成</button>
<button onClick={e => store.dispatch({type: 'against'})}>反对</button>
</div>
)
}
}
export default VoteFooter;