一、執行流程
全局有一個公共的容器(所有元件都可以操作),我們可以在某個元件中把全局容器中的資訊進行修改,而隻要全局資訊修改,就可以通知所有用到該資訊的元件重新渲染(類似于釋出訂閱)==》redux就是這種解決方案:redux隻有一個作用,就是為了實作元件之間的資訊互動。
1.執行createStore
- 建立一個容器store來用來管理公用的狀态資訊
- 建立一個事件池,用來存儲一些方法(方法一般都是用來通知某個元件重新渲染的)
- 當容器中的狀态改變,會自動通知事件池中的方法依次執行
2.基于store.getState可以擷取容器中存儲的狀态資訊(拿到狀态資訊就可以做資料綁定等操作了)
3.我們可以基于store.subscribe向事件池中追加方法(也可以移除事件池中的方法)
4.修改容器中的狀态資訊
- 首先雇一個管理者reducer,它就是用來修改容器中狀态的
- 當我們在元件中進行某些操作想要修改狀态資訊的時候,我們首先dispatch派發一個任務給reducer,并且告訴reducer如何去修改狀态資訊
公共狀态資訊都是reducer去改的,reducer記錄了所有修改狀态的行為方式,我們以後想要知道怎麼改的狀态,隻要看reducer即可。
- redux:不局限于任何架構(vue/react/angular/jquery...)
- react-redux:把redux進一步封裝,專門給react架構開發的(操作起來更簡潔)
- vuex:類似于redux的操作思想,專門為vue架構定制的
- dva:把redux/react-redux進一步封裝,操作更簡潔
- mobx:和redux不完全一緻,也是用來管控公共狀态的,隻不過操作起來更加簡單而已
畫一張簡易流程圖
2.具體代碼
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;
複制