Redux 在 React Hook 中的使用及其原理
淺談Redux
第一問 what ? 什么是Redux
State : 一個存放數(shù)據(jù)的容器 (一個對象)
const initState = {
count: 0,
}
Action : 一個 want to do 的過程 (計劃要做一個什么樣的操作)
ActionType是對Action的描述, 也是連接Action和Reducer的橋梁 本質(zhì)上是一個由ActionType和payload(數(shù)據(jù))組成的對象
export const increaseConstant = 'INCREASE' // ActionType
{
type: increaseConstant,
payload,
} // Action
Reducer : 一個 to do 的過程 (執(zhí)行Action計劃的操作)
case increaseConstant: // 當(dāng) ActionType 為 'INCREASE' 時, 執(zhí)行count++
return {
...state,
count: payload + 1
}
第二問 why ? 為什么要使用Redux
游戲初期階段, 數(shù)據(jù)單向傳遞, 父傳子

游戲進(jìn)入中期, 開始有少量非父子組件間需要通訊一些數(shù)據(jù)

游戲進(jìn)入后期, 開始需要大量的數(shù)據(jù)通訊

此時, 就是Redux的用武之地了, 使用Redux后流程如下

第三問 how to ? 怎么使用Redux

創(chuàng)建一個count組件
import React, { useState } from 'react'
const CountItem = (props) => {
const {
count,
increase,
} = props
return (
<>
{count}
<button onClick={increase}>Count++</button>
</>
)
}
const Count = () => {
const [count, setCount] = useState(0)
const increase = () => {
setCount(count + 1)
}
return (
<CountItem
count={count}
increase={increase}
/>
)
}
export default Count
封裝一個Dispatch函數(shù)
const dispatch = (action) => {
switch(action.type) {
case 'INCREASE':
return action.payload + 1
default:
break
}
}
改寫increase方法
const increase = () => {
- setCount(count + 1)
+ setCount(dispatch({type: 'INCREASE', payload: count}))
}
action.js => 返回action對象
const increaseCount = (payload) => {
return {
type: 'INCREASE',
payload
}
}
改寫increase方法
const increase = () => {
- setCount(dispatch({type: 'INCREASE', payload: count}))
+ setCount(dispatch(increaseCount(count)))
}
reducer.js => 進(jìn)行數(shù)據(jù)操作
const reducer = (state, action) => {
const { type, payload } = action
switch(type) {
case 'INCREASE':
return {
...state,
count: payload + 1
}
default:
return state
}
}
改寫dispatch函數(shù)
const dispatch = (action) => {
const state = {
count,
}
const newState = reducer(state, action)
return newState
}
改寫increase方法
const increase = () => {
- setCount(dispatch(increaseCount(count)))
+ setCount(dispatch(increaseCount(count)).count)
}
繼續(xù)改造dispatch函數(shù), 增加setter做映射
const dispatch = (action) => {
const state = {
count,
}
+ const setter = {
+ count: setCount
+ }
const newState = reducer(state, action)
+ for (let key in newState) {
+ setter[key](newState[key])
+ }
- return newState
}
改寫increase方法
const increase = () => {
- setCount(dispatch(increaseCount(count)).count)
+ dispatch(increaseCount(count))
}
在action中增加actionType
export const increaseConstant = 'INCREASE'
// 替換 action 和 reducer 中的 'INCREASE' 為 increaseConstant
改寫reducer
const reducer = {
count(state, action) {
const { type, payload } = action
switch(type) {
case increaseConstant:
return payload + 1
default:
break
}
},
}
combineReducers
const combineReducers = (reducer) => {
return (state, action) => {
let ret = {}
for (let key in reducer) {
ret[key] = reducer[key](state[key], action)
}
return {
...state,
...ret,
}
}
}
改寫dispatch
- const newState = reducer(state, action)
+ const newState = combineReducers(reducer)(state, action)

Redux + React 使用
import { createStore, combineReducers } from 'redux'
import reducer from './recuder'
const initState = {
count: 0,
}
const store = createStore(
combineReducers(reducer),
initState,
)
export default store
import { Provider } from 'react-redux'
import store from './store'
const App = () => {
return (
<Provider store={store}>
<Count />
</Provider>
)
}
export default App
import React from 'react'
import { connect } from 'react-redux'
import { increaseCount } from './action'
const CountItem = (props) => {
const {
count,
increase,
} = props
return (
<>
{count}
<button onClick={increase}>Count++</button>
</>
)
}
const Count = (props) => {
const {
count,
dispatch,
} = props
const increase = () => {
dispatch(increaseCount(count))
}
return <CountItem count={count} increase={increase} />
}
export default connect(
(state) => {
return state
},
(dispatch) => {
return { dispatch }
}
)(Count)
import React from 'react'
- import { connect } from 'react-redux'
+ import { useSelector, useDispatch } from 'react-redux'
import { increaseCount } from './action'
const CountItem = (props) => {
const {
count,
increase,
} = props
return (
<>
{count}
<button onClick={increase}>Count++</button>
</>
)
}
const Count = () => {
- const {
- count,
- dispatch,
- } = props
+ const count = useSelector(state => state.count)
+ const dispatch = useDispatch()
const increase = () => {
dispatch(increaseCount(count))
}
return <CountItem count={count} increase={increase} />
}
- export default connect(
- (state) => {
- return state
- },
- (dispatch) => {
- return { dispatch }
- }
- )(Count)
+ export default Count

評論
圖片
表情
