再谈Redux
2025年再聊前端状态管理似乎是一件不必要的事,毕竟相关文章已堆积得如山如海。但在这些文章或视频内容中,我并没有找到自己喜欢的方案,准确的说是使用方式。所以这篇文章不做技术分析,主要聊聊个人对状态管理的理解,并分享独特的redux使用的方式。
状态管理
先分享一个有趣的现象。或许是小厂的缘故,经常会在一些项目中看到vuex的身影,憋屈的是它经常会被用来存用户相关的数据,并且是只存当前登陆用户的相关信息,或者再存些权限、菜单数据。经手过的项目中用到状态管理的地方其实并不多,所以很多时候也没有太在意,毕竟用是挺好用的,但写起来还是不如组件状态那么简单。直到项目上用了React,并大范围使用redux后我对状态管理有了全新,确切的说是比较正确的认知。为了描述它,我专门画了张草图:

图上是一个令人痛苦的需求,点击“按钮2”点时候要将外层的“按钮1”设置为禁用状态。要求并不高,痛苦的地方在于他们间隔着好几层的嵌套(现实可能会更残酷些),如果通过事件传递,那么就涉及到所有隔着的组件调整,让它们帮忙传递这个事件。不难,但有点烦。当然,也可以换个思路,比如添加一个全局的事件管理程序,在“按钮1”所在的组件订阅一个事件,事件触发后禁用“按钮1”。当然还有很多类似的方式,如react context等。这个时候我们如果冷静的想想,控制按钮禁用的其实是一个属性,在组件中应该对应一个状态(比如:isDisable=true),如果“按钮2”点击后可以直接修改这个状态,好像会简单很多。这应该就是状态管理最基本的用法。为了方便理解,我还专门画了一张草图:

大概就这意思吧,状态管理就是将组件状态统一管理,方便组件间状态共享。状态管理是一个非常科学的设计,不仅能降低代码复杂度,还能降低组件的耦合程度。在复杂的场景下,结合中间件可以轻易的解决很多令人头疼的需求,高效、简洁,当然最重要的还是优雅!
这么好的设计为什么我就不常见呢?除了厂小的缘故,使用复杂应该是最大的障碍。遥记得java ssh架构下写一个接口需要修改很多个配置文件!好用的Redux早期管理一个状态至少也要改三个文件(action、reducer、selector),甚至更多,后来用上redux toolkit后也就少写一个action。
@nebula-note/redux-hooks
出于对编码工作的热爱,最近在写一个自己的代码笔记工具 Nebula Note,React技术栈,状态管理还是熟悉的Redux。Redux中Function Component组件化成本极低,所以我在使用React的时候几乎已完全放弃Class Component。开始并没考虑使用状态管理,但由于组件粒度越来越小,最后还是绷不住用上了。开始是reduxjs/toolkit,后来越写越觉得复杂,最后基于对Redux的熟悉,写了 @nebula-note/redux-hooks,目的是像使用hooks一样使用redux,所以将这个hooks命名useRedux。这里以最小的篇幅介绍下这个库的使用。
配置Store
Redux使用前需要做一些简单的配置,越简单的使用,配置就越简单,且这事只干一次。@nebula-note/redux-hooks是基于redux toolkit封装的,所以使用配置和redux toolkit完全一致。只不过configureStore这个函数需要从@nebula-note/redux-hooks中导入。下面是相关代码:
import { configureStore } from '@nebula-note/redux-hooks';
const store = configureStore();
使用hooks管理状态
下面是一个极度简单的使用案例,完整的。
import { useRedux } from '@nebula-note/redux-hooks';
type ExampleState = {
isDisabled:boolean
}
export const ExampleA = () => {
const { state, setState } = useRedux<ExampleState>('reduxKeyName', {isDisabled:false});
const handleDisabled= () => {
setState(true);
}
return(
<div>
<button disabled={state.isDisabled}>按钮1</button>
<button onclick={handleDisabled}>按钮2</button>
</div>
)
}
export const ExampleB = () => {
const { setState } = useRedux<ExampleState>('reduxKeyName', {isDisabled:false});
const handleDisabled= () => {
setState(true);
}
return(
<button onclick={handleDisabled}>按钮2</button>
)
}
使用心得
身为作者,完全有必要分享下自己是怎么使用这个工具的。
首先,使用@nebula-note/redux-hooks后不再需要编写reducer和action,useRedux会自动创建set和update两个action及reducer,使用中主要是应用这两个action去设置或更新状态,对应的是hooks暴露的两个函数,setState,updateState。setState是完全使用给定值,updateState则不需要提供完整的状态对象,如状态中存储的是{name, age},如果只想更新age,那么只需要传入age就可以了updateState({age:10})。
兼容方面@nebula-note/redux-hooks完全兼容redux toolkit,因为早期的时候项目中使用的是redux toolkit,所以重构也不是一次性完成的,因此并不用担心@nebula-note/redux-hooks的引入会对历史代码造成影响。如果需要使用想saga这样的中间件,还是需要自己定义action,@nebula-note/redux-hooks只是一个针对状态的轻量级解决方案。
最后,如何共享状态。useRedux第一个参数是redux的状态名称,所以只要状态名相同,在任何地方使用useRedux都能获取或修改这个状态数据。useRedux的第二个参数是状态默认值,这个值只会在状态数据初始化之前有效。
最后
引入状态管理后代码逻辑变得更清晰,使用@nebula-note/redux-hooks后代码变得更简洁,目前的设计完全是基于自己的需求在做,后续的更新中应该会加入一些新内容,但范围不会太大应该还是只针对基础状态管理。以上便是我对状态管理的理解,以及Redux使用的分享,喜欢请记得点赞。
再谈Redux的更多相关文章
- [转载]再谈百度:KPI、无人机,以及一个必须给父母看的案例
[转载]再谈百度:KPI.无人机,以及一个必须给父母看的案例 发表于 2016-03-15 | 0 Comments | 阅读次数 33 原文: 再谈百度:KPI.无人机,以及一个必须 ...
- Support Vector Machine (3) : 再谈泛化误差(Generalization Error)
目录 Support Vector Machine (1) : 简单SVM原理 Support Vector Machine (2) : Sequential Minimal Optimization ...
- Unity教程之再谈Unity中的优化技术
这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体 这一步主要是为了针对性能瓶颈中的”顶点 ...
- 浅谈HTTP中Get与Post的区别/HTTP协议与HTML表单(再谈GET与POST的区别)
HTTP协议与HTML表单(再谈GET与POST的区别) GET方式在request-line中传送数据:POST方式在request-line及request-body中均可以传送数据. http: ...
- Another Look at Events(再谈Events)
转载:http://www.qtcn.org/bbs/simple/?t31383.html Another Look at Events(再谈Events) 最近在学习Qt事件处理的时候发现一篇很不 ...
- C++ Primer 学习笔记_32_STL实践与分析(6) --再谈string类型(下)
STL实践与分析 --再谈string类型(下) 四.string类型的查找操作 string类型提供了6种查找函数,每种函数以不同形式的find命名.这些操作所有返回string::size_typ ...
- 再谈JSON -json定义及数据类型
再谈json 近期在项目中使用到了highcharts ,highstock做了一些统计分析.使用jQuery ajax那就不得不使用json, 可是在使用过程中也出现了非常多的疑惑,比方说,什么情况 ...
- C++ Primer 学习笔记_44_STL实践与分析(18)--再谈迭代器【下】
STL实践与分析 --再谈迭代器[下] 三.反向迭代器[续:习题] //P355 习题11.19 int main() { vector<int> iVec; for (vector< ...
- C++ Primer 学习笔记_43_STL实践与分析(17)--再谈迭代器【中】
STL实践与分析 --再谈迭代器[中] 二.iostream迭代[续] 3.ostream_iterator对象和ostream_iterator对象的使用 能够使用ostream_iterator对 ...
- 再谈IE的浏览器模式和文档模式
原文:再谈IE的浏览器模式和文档模式 以前在 “IE8兼容视图(IE7 mode)与独立IE7的区别”一文中曾经涉及过浏览器模式和文档模式,但二者的区别却不甚了了,现在有了新的认识,再补充一下. 1. ...
随机推荐
- 【转载】碰碰彭碰彭Jingxuan —— 带中国古筝走上戛纳红毯
视频地址: https://www.youtube.com/shorts/gl796527H1I
- 在PyCharm中打包Python项目并将其运行到服务器上的方法
在PyCharm中打包Python项目并将其运行到服务器上的方法 在PyCharm中打包Python项目并将其运行到服务器上的过程,可以分解为几个关键步骤:创建项目.设置项目依赖.打包项目.配置服务器 ...
- HttpWebRequest调用API
public void HttpWebRequestPost(){ string responseContent = string.Empty; var userNameAndPwd = new { ...
- 2024-11-16:哈沙德数。用go语言,如果一个整数能够被它的各个数位上数字的和整除, 我们称这个整数为哈沙德数(Harshad number)。 给定一个整数 x, 如果 x 是哈沙德数,则返回
2024-11-16:哈沙德数.用go语言,如果一个整数能够被它的各个数位上数字的和整除, 我们称这个整数为哈沙德数(Harshad number). 给定一个整数 x, 如果 x 是哈沙德数,则返回 ...
- Java Study For Six Day( 面向对象二)
static(静态)关键字 用于修饰成员(成员变量和成员函数) 被修饰后的成员具备以下的特点 随着类的加载而加载 优先于对象存在 被所有的对象共享 可以被类名直接调用 静态注意事项 静态方法只能访问静 ...
- golang工具之generate
示例: 大家经常碰到命名错误码.状态码的同时,又要同步写码对应的翻译,有没有感觉很无聊.这里举一个例子: package main import "fmt" // 定义错误 ...
- golang之函数工具库lancet
lancet(柳叶刀)是一个全面.高效.可复用的go语言工具函数库. lancet受到了java apache common包和lodash.js的启发. 简体中文 | English 特性 全面.高 ...
- Linux终端命令之screen
screen的功能 screen的功能大体有三个: 会话恢复:只要Screen本身没有终止,在其内部运行的会话都可以恢复.这一点对于远程登录的用户特别有用--即使网络连接中断,用户也不会失去对已经打开 ...
- 分布式对象存储之FDFS
1.它是一个开源的分布式文件系统,它对文件进行管理. 功能有:文件存储.文件同步.文件访问(文件的上传下载)等.特别适合以文件为主的在线服务. 2.fastDFS服务端有两个角色:跟踪器(tracke ...
- ThreeJs-05纹理材质高级操作
1.纹理操作 1.1 重复.旋转.位移.缩放 重复 但是要在水平方向上重复,还得允许 按照刚才的重复方式 如果设置为镜像重复 位移 旋转 1.2 翻转与alpha生成颜色 正常的图 不翻转默认是翻转的 ...