您现在的位置是:网站首页> 编程资料编程资料
useReducer createContext代替Redux原理示例解析_React_
2023-05-24
536人已围观
简介 useReducer createContext代替Redux原理示例解析_React_

前言
最近看到很多采用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 ( ); } 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 ( dispatch({ type: 'UPDATENAME' })}> {useSelector((state) => state.name)} ); } 效果如图:

可以看到,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 ( ); } A.jsx
import React, { useContext } from 'react'; import { reduxContent } from './index1'; export default function A() { const { redux, dispatch } = useContext(reduxContent); return ( dispatch({ type: 'UPDATENAME' })}> {redux.name} ); } 同样,子组件也可以对store中的状态进行get和dispatch,但是会出现这样的问题:

可以看到,Button组件并没有使用store中的内容,但是会随着A组件一起跟着重新渲染,原因其实就是采用这种方式store是存储在根组件的,根组件状态发生了变化(useReducer),子组件跟着一起重新渲染了,因此解决这个问题的思路其实和解决常规的子组件没变化一起被更新的思路是一样的。
可以采用 useMemo限制 + memo 浅比较。
因此只需要在App.jsx中这样修改:
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仍然是大型项目中最可靠的保障存在。
以上就是useReducer createContext代替Redux原理示例解析的详细内容,更多关于useReducer createContext代替Redux的资料请关注其它相关文章!
相关内容
- Vue如何监测数组类型数据发生改变的(推荐)_vue.js_
- better sqlite3安装node gyp原生模块编译prebuild-install_node.js_
- node gyp安装canvas原生模块编译node pregyp详解_node.js_
- vue在线预览word、excel、pdf、txt、图片的方法实例_vue.js_
- 第一次在Vue中完整使用AJAX请求和axios.js的实战记录_vue.js_
- 详细聊聊前端如何实现token无感刷新(refresh_token)_vue.js_
- Vue使用ajax(axios)请求后台数据的方法教程_vue.js_
- Vue实现简单可扩展甘特图的方法详解_vue.js_
- Vue项目代码之路由拆分、Vuex模块拆分、element按需加载详解_vue.js_
- WAPI与Wi-Fi是什么意思.以及有什么区别_安全其它_网络安全_
