React 状态管理器,我是这样选的

前言

我们的前端团队在一直深度使用 React ,从最早的 CRA ,到后来切换到 umijs ,从 1.x、2.x、3.x 再到现在的 4.x,其中有一点不变的,就是我们一直在使用基于 react-redux 思想的 dva 作为状态管理工具。

在状态共享这方面,不像 VuexReact 的官方并没有强力推荐某种封装方案,所以 React 的状态管理工具五花八门,百花齐放。其中就有:

  • 做什么都要 dispatchredux 流派。包括:react-reduxdva、新星代表 zustand
  • 响应式流派 mobx。以及新星代表 valtio ,以及一个很有特点的库 resso
  • 原子状态流派。来自 facebook 开源的 recoil ,以及新星代表 jotai
  • 完全体 hooks 流派。hoxretoumijs@4 内置数据流,包括 Vue 官方推荐的新状态管理工具 pinia 也是这个流派。

更为重要的一点是,传统的 MVC 模式,建议我们将视图层的逻辑层分离。而在 dva 中,页面即视图,effects 则被我们用于业务逻辑的编写。在这种思想的影响下,不论是简单还是复杂的页面,我们都习惯去创建一个 dva-model,再加上 dispatch 都不是强依赖关系,久而久之, model 越来越臃肿,关系越来越难找,吐槽声越来越大。

随着技术不断发展,我们终归是要摆脱繁琐的 dva,寻找一个新的状态管理工具,来减少我们这一块的代码量,保护我们的秀发。

所以经过了一系列的试点,我也来介绍一下各流派的优缺点和我个人的倾向。

我们需要什么样的状态管理工具

可能不需要?

我们阅读一些状态管理工具的文档时候,可能就会先被这样一篇文章甩在脸上:《你可能不需要状态管理工具》

是的,不管是用起来繁琐的 dva 还是更为简洁的 recoil ,我们都不应该滥用状态管理工具。滥用只会给我们后面的维护和重构带来麻烦。

什么时候需要?

状态管理工具的作用,就是状态的共享,当共享状态发生变化,所有使用方都会触发重新渲染。所以,当然是状态需要被多方共享的时候,才需要使用状态管理工具了。比如:

  • 当前登录的用户信息,姓名,角色,所属组织等
  • 静态数据字典的缓存
  • 需要 keep-alive 的数据(不一定用)
  • 页面功能复杂,模块化后,模块之间仍需要共享的数据

请不要在【基础组件】中使用共享的状态,【基础组件】应该保持自身的独立性,做到高内聚

对状态管理工具的要求?

随着项目经验的积累,我总结出了状态管理工具应该满足的几个特性:

1.共享状态(基础),能够满足上面列举的几个场景;
2.共享业务逻辑,比如修改个人密码后需要退出并跳转至登录页(在菜单栏和个人中心都要调用,相同的逻辑不应该写多次);
3.共享状态模块化,即按不同业务逻辑,分开不同的文件创建共享状态。
4.再复杂一些的,涉及到共享状态之间的依赖,比如当我修改当前登录人的角色之后(比如从”项目经理“切换至”系统管理员“),记录菜单权限的状态也需要更新。
5.使用时,有清晰的依赖来源(import from)。
6.对 TypeScript 支持良好,易编写。

主流状态管理工具都是怎么做的

传统流派 dva

对比 dvaVuex 不能说是非常相似,只能说是一模一样了。

  • dvastateVuexstate,用于存放需要共享的状态。
  • dvaredu
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要实现复下拉框(Checkbox Dropdown)的默认值,你可以使用 React状态(state)来管理中的值。下面是一个示例代码: 首先,创建一个复下拉框组件(CheckboxDropdown): ```jsx import React, { useState } from 'react'; const CheckboxDropdown = () => { const [selectedValues, setSelectedValues] = useState([]); const [isOpen, setIsOpen] = useState(false); const options = [ { value: 'option1', label: '项1' }, { value: 'option2', label: '项2' }, { value: 'option3', label: '项3' }, ]; const handleToggle = () => { setIsOpen(!isOpen); }; const handleSelect = (value) => { if (selectedValues.includes(value)) { setSelectedValues(selectedValues.filter((val) => val !== value)); } else { setSelectedValues([...selectedValues, value]); } }; return ( <div> <div onClick={handleToggle}>点击择</div> {isOpen && ( <div> {options.map((option) => ( <label key={option.value}> <input type="checkbox" checked={selectedValues.includes(option.value)} onChange={() => handleSelect(option.value)} /> {option.label} </label> ))} </div> )} </div> ); }; export default CheckboxDropdown; ``` 然后,在你的父组件中使用这个复下拉框组件,并通过设置默认值来添加默认项: ```jsx import React from 'react'; import CheckboxDropdown from './CheckboxDropdown'; const App = () => { return ( <div> <h1>复下拉框</h1> <CheckboxDropdown /> {/* 默认没有中任何项 */} {/* 或者添加默认项 */} {/* <CheckboxDropdown selectedValues={['option1', 'option2']} /> */} </div> ); }; export default App; ``` 在上面的代码中,我们在父组件中使用了 `CheckboxDropdown` 组件,并且可以通过 `selectedValues` 属性来设置默认项。如果不传入 `selectedValues` 属性,则默认没有中任何项。如果你想要添加默认项,可以将项值作为数组传递给 `selectedValues` 属性。 这样,你就可以实现复下拉框添加默认值了。希望能对你有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值