網站首頁 編程語言 正文
前言
最近看到很多采用useReducer + createContext
實現一個簡易的redux
的方案,今天親自試了一下,發現還是會有一些區別的。
采用react-redux實現
這里使用react-redux
實現一個簡單的狀態管理例子。
App.jsx根組件
import React from 'react'; import { Button } from './Button'; import { createStore } from 'redux'; import { Provider } from 'react-redux'; import A from './a'; export default function ButtonDemo1() { const reducer = (state, action) => { const { name, theme } = state; switch (action.type) { case 'UPDATENAME': return { ...state, name: `${name} + 1`, }; case 'UPDATETHEME': return { ...state, theme: theme === 'dark' ? 'light' : 'dark', }; default: return state; } }; const store = createStore(reducer, { name: 'fx', theme: 'dark', }); return ( <Provider store={store}> <div> <Button /> <A /> </div> </Provider> ); }
A組件用于dispatch
和接收store
。
A.jsx
import React, { useContext } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { reduxContent } from './index1'; export default function A() { const dispatch = useDispatch(); return ( <div onClick={() => dispatch({ type: 'UPDATENAME' })}> {useSelector((state) => state.name)} </div> ); }
效果如圖:
可以看到,Button
組件未使用redux store
,因此正常渲染了一次。
采用react hooks模擬redux實現
這里采用useReducer
+ createContext
模擬實現一個redux
:
App.jsx
import React, { useReducer, createContext } from 'react'; import { Button } from 'concis'; import A from './a'; export const reduxContent = createContext({}); export default function ButtonDemo1() { const reducer = (state, action) => { const { name, theme } = state; switch (action.type) { case 'UPDATENAME': return { ...state, name: `${name} + 1`, }; case 'UPDATETHEME': return { ...state, theme: theme === 'dark' ? 'light' : 'dark', }; default: return state; } }; const [redux, dispatch] = useReducer(reducer, { name: 'fx', theme: 'dark', }); return ( <reduxContent.Provider value={{ redux, dispatch }}> <Button /> <A /> </reduxContent.Provider> ); }
A.jsx
import React, { useContext } from 'react'; import { reduxContent } from './index1'; export default function A() { const { redux, dispatch } = useContext(reduxContent); return ( <div onClick={() => dispatch({ type: 'UPDATENAME' })}> {redux.name} </div> ); }
同樣,子組件也可以對store
中的狀態進行get
和dispatch
,但是會出現這樣的問題:
可以看到,Button
組件并沒有使用store
中的內容,但是會隨著A
組件一起跟著重新渲染,原因其實就是采用這種方式store
是存儲在根組件的,根組件狀態發生了變化(useReducer
),子組件跟著一起重新渲染了,因此解決這個問題的思路其實和解決常規的子組件沒變化一起被更新的思路是一樣的。
可以采用 useMemo
限制 + memo
淺比較。
因此只需要在App.jsx
中這樣修改:
const renderButton = React.useMemo(() => { return <Button />; }, []); return ( <reduxContent.Provider value={{ redux, dispatch }}> <div style={{ display: 'flex', flexWrap: 'wrap' }}> {renderButton} <A /> </div> </reduxContent.Provider> ); }
Button.jsx
const Button = (props) => { ...... }) export default React.memo(Button);
異步action
同樣,如果需要異步dispatch
的話,簡單的場景其實單純使用異步操作就可以完成,但是在復雜的場景下很難對于異步流進行管理和維護,這時就需要借助redux中間件
了,類似redux-thunk
、redux-saga
,而這也是使用hooks
無法實現的,無法處理副作用,攔截action
去更好的reducer
。
總結
當然,并不是說采用react hooks
所實現的狀態管理方式沒有好處,這樣可以更加貼合react
原生,采用react
自身所提供的hook,并且可以減少項目中的redux
各種實例、減少代碼體積,對于小型項目或是不需要很多全局狀態的項目,這種方式確實是不錯的選擇。但是redux
仍然是大型項目中最可靠的保障存在。
原文鏈接:https://juejin.cn/post/7161458530984132622
相關推薦
- 2022-05-12 HarmonyOS 頁面跳轉
- 2022-10-22 如何在Go中使用Casbin進行訪問控制_Golang
- 2022-04-06 如何將Python編譯成C語言_python
- 2023-01-07 Python中sys.argv用法圖文詳解_python
- 2022-07-10 修改redo默認傳輸用戶sys到其他---redo_transport_user參數
- 2023-02-09 詳解如何使用Python實現復制粘貼的功能_python
- 2023-12-08 uniapp 頁面添加背景圖片不顯示
- 2022-04-05 vxe-table中vxe-grid的使用
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支