Redux在React Hook中的使用及其原理
2021/1/25 14:08:17
本文主要是介绍Redux在React Hook中的使用及其原理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
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去了, 我的小伙伴还等我带他上白银呢, 一帮混子, 带不动.
这篇关于Redux在React Hook中的使用及其原理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23实现OSS直传,前端怎么实现?-icode9专业技术文章分享
- 2024-11-22在 HTML 中怎么实现当鼠标光标悬停在按钮上时显示提示文案?-icode9专业技术文章分享
- 2024-11-22html 自带属性有哪些?-icode9专业技术文章分享
- 2024-11-21Sass教程:新手入门及初级技巧
- 2024-11-21Sass学习:初学者必备的简单教程
- 2024-11-21Elmentplus入门:新手必看指南
- 2024-11-21Sass入门:初学者的简单教程
- 2024-11-21前端页面设计教程:新手入门指南
- 2024-11-21Elmentplus教程:初学者必备指南
- 2024-11-21SASS教程:从入门到实践的简单指南