你不需要总是在 React 中使用 useState

news/2024/9/24 18:53:27/

在我审查的一个拉取请求中,我注意到在许多拉取请求中看到的一种模式。React 组件具有多个 UI 状态,例如 loadingerrorsuccess

作者使用了多个 useState 钩子来管理这些状态,这导致代码难以阅读且容易出错,例如:

const MyComponent = () => {const [loading, setLoading] = useState(false)const [error, setError] = useState(false)const [success, setSuccess] = useState(false)return (<div>{loading && !error && !success && <p>Loading...</p>}{error && !loading && !success && <p>Error occurred</p>}{success && !loading && !error && <p>Operation completed successfully</p>}</div>)
}

这些状态彼此不同。当 loadingtrue 时,errorsuccess 应该为 false。使用多个 useState 钩子可能会导致意外行为,例如意外 true 同时设置两个状态。

相反,请考虑使用有限状态机(FSM) 模式。FSM 只允许有限数量的状态。在上面的 UI 示例中,单个 useState 可以更稳健地管理当前状态,并且出错的风险更低,如下所示:

import { useState } from 'react'type State = 'loading' | 'error' | 'success'const MyComponent = () => {const [state, setState] = useState<State>('loading')const handleClick = () => {setState('loading')// Simulate an async operationsetTimeout(() => {setState('success')}, 2000)}return (<div>{state === 'loading' && <p>Loading...</p>}{state === 'error' && <p>Error occurred</p>}{state === 'success' && <p>Operation completed successfully</p>}<button onClick={handleClick}>Click me</button></div>)
}

在某些情况下,例如使用 Tanstack 查询来获取数据时,useQuery 无需单独 useState 挂钩 来设置 loadingerrorsuccess 状态:

const MyComponent = () => {const { data, isLoading, error } = useQuery(...)if (isLoading) {return <p>Loading...</p>}if (error) {return <p>Error occurred</p>}return <p>Operation completed successfully {data}</p>
}

让我们考虑另一个名为 locked 的状态,它根据服务器发送的 403 状态代码显示用户是否已解锁该功能。通常情况下,开发人员可能会使用 useStateuseEffect 来管理该状态,这可能会增加不必要的复杂性:

const MyComponent = () => {const [locked, setLocked] = useState(false)const { data, isLoading, error } = useQuery(...)useEffect(() => {if (error && error.status === 403) {setLocked(true)}}, [error])if (locked) {return <p>You are locked out</p>}
}

更好的方法是直接从 error 中推导出锁定状态:

const MyComponent = () => {const { data, isLoading, error } = useQuery(...)if (isLoading) {return <p>Loading...</p>}const locked = error?.status === 403if (locked) {return <p>You are locked out</p>}
}

这种方法可以避免使用 useStateuseEffect 进行额外的状态管理。

在编写 React 组件时,请务必考虑是否有必要使用 useStateuseEffect。通常情况下,它们是不必要的。


http://www.ppmy.cn/news/1451286.html

相关文章

低代码工业组态数字孪生平台

2024 两会热词「新质生产力」凭借其主要特征——高科技、高效能及高质量&#xff0c;引发各界关注。在探索构建新质生产力的重要议题中&#xff0c;数据要素被视为土地、劳动力、资本和技术之后的第五大生产要素。数据要素赋能新质生产力发展主要体现为&#xff1a;生产力由生产…

Linux / Ubuntu 备份数据

Linux / Ubuntu 备份数据 需要备份的文件tar 工具备份/打包过程恢复/解包过程 流程自动化start_backup.shserver_backup.sh 同步发布在个人笔记Linux / Ubuntu 备份数据 需要备份的文件 对于我们的 linux 服务器&#xff08;当然也适用于桌面端&#xff09;&#xff0c;时常进…

LeetCode 131 —— 分割回文串

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 首先&#xff0c;按照 LeetCode 5——最长回文子串 中的思路&#xff0c;我们先求出 d p dp dp&#xff0c;这样我们就知道了所有的子串是否是回文子串。 然后&#xff0c;我们进行一个 dfs 搜索&#xff0c;起…

(汇总)vue中在不同页面之间-4种传递参数的方式

Vue项目页面间传递参数和参数存储有很多种&#xff0c;常见的&#xff1a; &#xff08;参考链接&#xff1a;www.qinglite.cn/doc/4603647… url里加参数&#xff0c;比如&#xff1a;/find?idxxx&#xff0c;或/find/xxx&#xff0c;适合少量数据&#xff0c;优点是刷新页面…

企业计算机服务器中了lockbit勒索病毒如何处理,lockbit勒索病毒解密流程建议

在虚拟的网络世界里&#xff0c;人们利用网络获取信息的方式有很多&#xff0c;网络为众多企业提供了极大便利性&#xff0c;也大大提高了企业生产运营效率&#xff0c;方便企业开展各项工作业务。但随着网络技术的不断发展与应用&#xff0c;越来越多的企业开始关注企业网络数…

SMB 协议详解之-TreeID原理和SMB数据包分析技巧

在前面分析SMB协议数据包的过程中,这里,可以看到在SMB协议中存在很多的ID,即Unique Identifiers。那么这些ID表示什么含义?在实际分析数据包的过程中如何根据这些ID进行过滤分析?本文将介绍SMB/SMB2中的tree id ,并介绍如何通过tree id 快速的分析SMB数据包中各种命令交互…

本地基于知识库的大模型的使用教程

本地基于知识库的大模型的使用教程 启动 双击 大模型启动.bat文件&#xff0c;内容如下&#xff1a; cmd /k "cd /d G:\Anaconda3\Scripts && activate.bat && cd /d D:\docdb_llm && conda activate python3.11 && python startup.py…

如何解决Go中uint类型溢出问题

如何解决Go中uint类型溢出问题 Golong的uint类型溢出问题通常会发生在大量的运算中&#xff0c;特别是涉及到大量循环和大数运算中。当uint类型的值超过其最大值时&#xff0c;会发生溢出&#xff0c;从最小值开始循环&#xff0c;一般有如下几种解决办法&#xff1a; 1. 使用…