文章目錄
-
- redux 簡介
- redux 三大原則
-
- 單一資料源
- State 是隻讀的
- 使用純函數來執行修改
- redux 核心理念
-
- 安裝依賴
- store
- action
- reducer
- constant.js
- state.js
- 頁面使用
redux 簡介
redux 是一個幫助我們管理State的容器:redux是JavaScript的狀态容器,提供了可預測的狀态管理
redux 不是隻能用于 react 中的,它還可以用在 vue 等其它架構中
redux 的主要作用就是:集中式管理(讀/寫)react 應用中多個元件共享狀态
redux 三大原則
單一資料源
- 整個應用程式的state被存儲在一顆object tree中,并且這個object tree隻存儲在一個 store 中
- 單一的資料源可以讓整個應用程式的state變得友善維護、追蹤、修改
State 是隻讀的
- 唯一修改State的方法一定是觸發action(一個用于描述已發生事件的普通對象),不要試圖在其他地方通過任何的方式來修改State
- 這樣就確定了View或網絡請求都不能直接修改state,它們隻能通過action來描述自己想要如何修改state
- 這樣可以保證所有的修改都被集中化處理,并且按照嚴格的順序來執行,是以不需要擔心race condition(竟态)的問題
使用純函數來執行修改
- 通過reducer将 舊state和 actions聯系在一起,并且傳回一個新的State
- 随着應用程式的複雜度增加,我們可以将reducer拆分成多個小的reducers,分别操作不同state tree的一部分
- 但是所有的reducer都應該是純函數,不能産生任何的副作用
redux 核心理念
dispatch(派發器觸發actions中的對應方法)=>actions(具體去觸發對應的reducer的方法)=>reducer(j具體的修改state中的資料的方法)=>subscribe(訂閱者,state中的資料變化,就會觸發)=>unsubscribe(取消訂閱)
安裝依賴
yarn add redux redux-thunk
store
import {createStore,applyMiddleware} from "redux"
import thunk from "redux-thunk"
import reduce from "./reduce"
const store =createStore(reduce,applyMiddleware(thunk))
export default store
如果有多個reducer需要合并
import {createStore,applyMiddleware,combineReducers} from "redux"
import thunk from "redux-thunk"
import reduce from "./reduce"
// 如果有多個reducer 需要連接配接後使用,這樣,在使用 state中的資料,需要 .count
const allReducers =combineReducers({
count:reduce
})
const store =createStore(allReducers,applyMiddleware(thunk))
export default store
actions不受影響
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setCount(store.getState().count.count)
})
return () => {
unsubscribe()
}
}, [])
action
派發事件中心(不能修改資料)
import {
INCREMENT,
DECREMENT
} from "./constant"
export const incrementAction= data =>({
type:INCREMENT,
data
})
export const decrementAction= data =>({
type:DECREMENT,
data
})
export const decrementActionAsync= data =>{
return dispatch=>{
setTimeout(()=>{
dispatch(incrementAction(data))
},1000)
}
}
reducer
真正修改資料的地方
import initState from "./state"
import {
INCREMENT,
DECREMENT
} from "./constant"
export default function createRender(state = initState, action) {
console.log(state);
switch (action.type) {
case INCREMENT:
return { ...state, count: state.count + action.data }
case DECREMENT:
return { ...state, count: state.count - action.data }
default:
return state
}
}
constant.js
const INCREMENT="increment"
const DECREMENT="decrement"
export {
INCREMENT,
DECREMENT
}
state.js
export default {
count : 0
}
頁面使用
import React, { memo, useEffect, useState } from 'react'
import store from "./store"
import { incrementAction, decrementAction, decrementActionAsync } from "./store/actions"
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setCount(store.getState().count)
})
return () => {
unsubscribe()
}
}, [])
return (
<div>
<h2>
{count}
</h2>
<button onClick={() => {
store.dispatch(incrementAction(1))
}}>
+1
</button>
<hr />
<button onClick={() => {
store.dispatch(decrementAction(5))
}}>
-5
</button>
<hr />
<button onClick={() => {
store.dispatch(decrementActionAsync(5))
}}>
異步+5
</button>
</div>
)
}
export default memo(App)