网站首页 > 技术文章 正文
React使开发人员可以完全自由地在组件中管理状态。React具有两种类型的组件:类组件和功能组件,他们是在React v16中引入的。
类组件使用的方法被用来管理状态,如:this.state和this.setState针对状态,组件在被安装后使用componentDidMount()运行副作用。
对于上面的内容,你如果有兴趣,可以阅读有关这些方法的其它信息:
相关链接:https://reactjs.org/docs/state-and-lifecycle.html
但是,由于大部分React开发人员目前都在使用React功能组件,因此本文我们会专注在功能组件及其状态,这些功能是通过React钩子进行管理的:
相关链接:https://reactjs.org/docs/hooks-intro.html
在本文,我们会介绍一些近期发现的最佳实践(或许你已经了解,那么请忽略本文),这些最佳实践用于管理功能组件中的状态,并真正意义上利用了React钩子API,下面就让我们开始!
1 . 把useReducer用于复杂状态
useReducer钩子是功能强大的React钩子,用于处理不需要第三方依赖项的复杂状态管理,并且它减少了每次渲染时重新创建的数据量。但有时,useState钩子解决不了问题,尤其是在处理涉及大型对象的复杂状态行为时。
当把环境和Typescript结合使用时,useReducer的功能会非常强大。
让我们看一下如何在现实中利用上它:
const BasicComponent = () => {
const [isOpen, setIsOpen] = useState(false);
const [name, setName] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const [id, setid] = useState('');
return (
// ...
)
}
// Refactored this is a lot easier to read, more modular, and faster!
const initialState = {
isOpen: false,
name: '',
isLoading: false,
error: null,
id: ''
}
const reducer = (state, action) => {
switch (action.type) {
case 'setIsOpen':
return { ...state, isOpen: action.payload }
break;
// ...
default:
return state;
}
}
const BetterComponent = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
// ...
)
}
2 . Custom Hooks
当使用React钩子时,有可能会在一个组件中出乎预料获得复杂状态逻辑,该组件利用多种类型的钩子来实现一个目的。
还好,我们是可以制作自定义的React钩子的,以便把复杂的逻辑包含在单个可访问的钩子中;而这对于表单、切换、异步行为以及其他在组件中引发一堆钩子的情况会非常有用。
下面来看一个自定义钩子的示例,以帮助在项目列表中切换项目,代码如下:
import { useState } from 'react';
type UseToggle<T> = [T[], (item: any) => void, (items?: T[]) => void];
const useToggle = <T = any>(defaultValues?: T[]): UseToggle<T> => {
const [items, setItems] = useState<T[]>(defaultValues || []);
const toggleItem = (item: any) => {
if (items.includes(item)) {
setItems((prev) => prev.filter((i) => i !== item));
} else {
setItems((prev) => prev.concat(item));
}
};
const reset = (newItems?: T[]) => setItems(newItems || []);
return [items, toggleItem, reset];
};
export default useToggle;
通过将所有这些逻辑抽象到自定义的React钩子中,这不仅易于阅读,而且可在我们的应用中重复使用!
3 . 全局状态管理
恐怕多数情况下,你不需要状态管理库,实际上仅仅会在处理复杂状态的大型应用中才可能会面对需要引入外部库进行管理的情况,即便在这种情况下,如果的确不能仅仅以Context API为条件在组件间共享数据,还需要慎重考虑一下。
假设你已经决定需要外部状态管理工具,我们会建议查看一下Recoil,它是用于管理全局状态的超轻量级简便工具,而另一个受欢迎的库是Redux。(关于如何有效使用这些工具,本文先不做探讨)
4 . 使用数据提取库
从外部API提取数据,这貌似是一个简单的问题,但是一旦你需要在内存中缓存数据(以减少API调用的次数),对其进行更新并在多个位置进行访问,就会变得非常复杂。
值得庆幸的是,有诸如React Query之类的现代数据获取库,
相关链接:https://react-query.tanstack.com/
可以有效地从外部源获取、缓存、作废和刷新数据;还可以把它们用于把数据发送到某些外部客户端,以便真正涵盖与服务器交互的整个工作流程。
更棒的是,其中一些库譬如Apollo Client,
相关链接:https://www.apollographql.com/docs/react/
包含了状态管理,能够以可预测、声明和可读的方式处理包括获取数据、数据缓存以及自动更新UI的完整过程。
结论
管理React状态可能会很复杂,但是我希望借助这些技巧,以高效且易读的方式进行操作。
猜你喜欢
- 2024-10-01 React状态管理专题:什么是Redux(react+redux)
- 2024-10-01 Next.js 14 正式发布(next.itellyou.cn)
- 2024-10-01 React:组件的生命周期(react组件的生命周期函数)
- 2024-10-01 react native 封装一个公用的数据请带上拉分页下拉刷新的组件
- 2024-10-01 React是一个前端开发项目的JavaScript库
- 2024-10-01 「最简教程」每天一篇,轻松搞定 React——状态提升
- 2024-10-01 千万级项目后台菜单导航设计及react antd实现
- 2024-10-01 这就是你日思夜想的 React 原生动态加载
- 2024-10-01 React 渲染的未来(react 渲染流程)
- 2024-10-01 React 最简单的入门应用项目(react简单吗)
- 08-01Linux Systemd入门
- 08-01使用 Checkmk 监控 Oracle 服务器
- 08-01核心库CPU飙到99%了!我发现很多DBA都不会看日志……
- 08-01China's CETC Kingbase Unveils AI-Powered Database Appliances Amid Rising Demand for Intelligent Data Infrastructure
- 08-01Docker安装部署Oracle/Sql Server
- 08-01Oracle数据库安装 | 步骤详细
- 08-01基于Springboot + vue实现的社团管理系统
- 08-01前端开发如何用Mock.js进行数据接口模拟
- 1520℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 623℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 526℃MySQL service启动脚本浅析(r12笔记第59天)
- 492℃启用MySQL查询缓存(mysql8.0查询缓存)
- 491℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 479℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 460℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 458℃MySQL server PID file could not be found!失败
- 最近发表
-
- Linux Systemd入门
- 使用 Checkmk 监控 Oracle 服务器
- 核心库CPU飙到99%了!我发现很多DBA都不会看日志……
- China's CETC Kingbase Unveils AI-Powered Database Appliances Amid Rising Demand for Intelligent Data Infrastructure
- Docker安装部署Oracle/Sql Server
- Oracle数据库安装 | 步骤详细
- 基于Springboot + vue实现的社团管理系统
- 前端开发如何用Mock.js进行数据接口模拟
- 使用vite为vue项目配置@别名
- 基于Springboot + vue3实现的教务管理系统
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- js~~ (67)
- node_modules怎么生成 (87)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)