Hello, 各位怯懦的小伙伴, 大家好, 我是你们的嘴强王者小五, 身体健康, 脑子没病.
自己有丰盛的脱发技巧, 能让你一跃成为资深大咖.
一看就会一写就废是自己的宗旨, 菜到抠脚是自己的特点, 低微中透着一丝丝坚强, 傻人有傻福是对我最大的刺激.
欢送来到
小五
的随笔系列
之Redux 在 React Hook 中的应用及其原理
.
浅谈 Redux
上面将从what
, why
, how to
三个方面来说说 Redux
第一问 what ❓ 什么是 Redux
将一个 web
利用拆分成视图层与数据层, Redux
就是保留其数据的一个容器, 其本质就是保护一个存储数据的对象.
- State : 一个存放数据的容器 (一个对象)
const initState = {count: 0,}
-
Action : 一个 want to do 的过程 (打算要做一个什么样的操作)
ActionType
是对Action
的形容, 也是连贯Action
和Reducer
的桥梁- 实质上是一个由
ActionType
和payload
(数据)组成的对象
export const increaseConstant = 'INCREASE' // ActionType
{
type: increaseConstant,
payload,
} // Action
- Reducer : 一个 to do 的过程 (执行 Action 打算的操作)
case increaseConstant: // 当 ActionType 为 'INCREASE' 时, 执行 count++
return {
...state,
count: payload + 1
}
第二问 why ❓ 为什么要应用 Redux
当你不晓得是否须要应用 Redux
的时候, 那就是不须要应用.
上面一组动图很好的形容了一个应用程序的开发过程, 及何时须要 Redux
.
图片起源及原文链接
- 游戏初期阶段, 数据单向传递, 父传子
- 游戏进入中期, 开始有大量非父子组件间须要通信一些数据
- 游戏进入前期, 开始须要大量的数据通讯
- 此时, 就是
Redux
的用武之地了, 应用Redux
后流程如下
第三问 how to ❓ 怎么应用 Redux
在说应用办法之前, 咱们先来从头到尾模仿一个 Redux
的过程, 只有了解原理, 应用起来那不是小菜一碟.
Let’s go, come on baby!
上面咱们就用一个简略的计数器的例子来模仿实现一个 Redux 的过程:
创立一个 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
这样一个简略的 count 组件就创立好了, 当初, 咱们想把对数据的操作独自封装成一个办法名为dispatch
, 传递的参数为一个Action
格局: {type: xxx, payload: xxx}
封装一个 Dispatch 函数
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
对象也抽离进去, 不便复用, 新建action.js
.
action.js => 返回 action 对象
const increaseCount = (payload) => {
return {
type: 'INCREASE',
payload
}
}
改写 increase 办法
const increase = () => {- setCount(dispatch({type: 'INCREASE', payload: count}))
+ setCount(dispatch(increaseCount(count)))
}
接下来咱们把 dispatch
中的事件操作抽离到 reducer
中, 新建reducer.js
.
reducer.js => 进行数据操作
const reducer = (state, action) => {const { type, payload} = action
switch(type) {
case 'INCREASE':
return {
...state,
count: payload + 1
}
default:
return state
}
}
改写 dispatch 函数
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)
}
接下来, 咱们把 set
办法也拿到 dispatch
中, 让所有操作都在 dispatch
中实现.
持续革新 dispatch 函数, 减少 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.type
是连贯 action
和reducer
的桥梁, 咱们能够将 actionType
定义为常量独自保留.
在 action 中减少 actionType
export const increaseConstant = 'INCREASE'
// 替换 action 和 reducer 中的 'INCREASE' 为 increaseConstant
基于现有场景, 如果咱们有另一个性能, 而目前的 reducer 并不能帮忙咱们很好的把不同的性能划分开来, 咱们革新一下 reducer
, 革新成一个对象, 用对象的key
去辨别性能.
改写 reducer
const reducer = {count(state, action) {const { type, payload} = action
switch(type) {
case increaseConstant:
return payload + 1
default:
break
}
},
}
这时咱们要遍历 reducer
, 找到正确的key
, 能力让程序正确执行, 咱们新建combineReducers.js
来实现这步操作.
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
函数, 使其反对以后格局reducer
.
改写 dispatch
- const newState = reducer(state, action)
+ const newState = combineReducers(reducer)(state, action)
至此, 一个 redux
的实现过程就实现了, 接下来, 咱们理论用一用redux
. 其实, 当实现上述操作的时候, 怎么用就曾经说的差不多了.
Redux + React 应用
action
, reducer
, Count
组件同上, Count 组件须要简略改写下.
新建store.js
import {createStore, combineReducers} from 'redux'
import reducer from './recuder'
const initState = {count: 0,}
const store = createStore(combineReducers(reducer),
initState,
)
export default store
新建app.jsx
, 引入store
import {Provider} from 'react-redux'
import store from './store'
const App = () => {
return (<Provider store={store}>
<Count />
</Provider>
)
}
export default App
改写 Count
组件
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)
接下来, 咱们改写成 hook
的写法
改写 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
至此, 本篇文章就到此结束了, 大家能够写个简单一点的组件练习下, 比方 todoList, 手动滑稽. 逃了逃了, 我要去 timi 去了, 我的小伙伴还等我带他上白银呢, 一帮混子, 带不动.