我对 use() 钩子的思考——深入探讨 React 的最新实验功能
来源:dev.to
时间:2024-11-28 08:40:06 470浏览 收藏
大家好,今天本人给大家带来文章《我对 use() 钩子的思考——深入探讨 React 的最新实验功能》,文中内容主要涉及到,如果你对文章方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢!
react 19 已经发布了,它带来了许多新功能,例如服务器组件、指令(使用客户端和使用服务器)、新钩子(例如 useoptimistic()、useformstatus() 和实验性 use()) hook,这就是我今天要讲的内容。
什么是 use() 挂钩?
use() 钩子是一项新功能,可让您直接在组件中处理 promise。它本质上是一种在组件内部解开 promise 并更简洁地处理异步数据的方法。
import { use } from 'react'; // example async function async function fetchuserdetails(id) { const response = await fetch(`localhost:3000/api/users/${id}`); return response.json(); } function userprofile({ id }) { // use() will suspend the component while the promise resolves const user = use(fetchuser(id)); return <div>hello, {user.name}!</div>; }
use() 钩子代表了 react 处理异步数据方式的重大转变,使其更加直观并降低了管理异步状态的复杂性。
use() 钩子的主要特点:
promise 处理:use() 可以处理组件中任何级别的 promise。它会在等待 promise 解决时自动挂起组件,并且与 react 的 suspense 边界配合使用。
错误处理更直观:
try { const data = use(riskyoperation()); return <success data={data} />; } catch (error) { return <errorboundary error={error} />; }
- 资源缓存:react 自动缓存 use() 的结果 — 不会不必要地重新获取相同的 promise,从而以更少的代码行优化性能。
比较 use() 与 usestate() useeffect() 模式
假设我们有一个 api 获取函数来获取用户帖子,我们需要在应用程序中全局访问帖子。
// global api fetch function async function fetchuserposts(userid: string) { const response = await fetch(`/api/users/${userid}/posts`); return response.json(); }
以下是如何在用户配置文件组件中获取帖子,并使用 usestate 挂钩和 useeffect 挂钩将其数据作为帖子状态传递,同时必须具有我们习惯的加载状态和错误状态。
// example 1: basic data fetching // traditional approach using usestate and useeffect function userprofilepost({ postid }: { postid: string }) { const [post, setpost] = usestate<any>(null); const [isloading, setisloading] = usestate(true); const [error, seterror] = usestate<error | null>(null); useeffect(() => { setisloading(true); seterror(null); fetchuserposts(userid) .then(data => { setpost(data); }) .catch(err => { seterror(err); }) .finally(() => { setisloading(false); }); }, [userid]); if (isloading) return <div><loading /></div>; if (error) return <div><error /></div>; if (!post) return null; return ( <div> <h1>{post.title}</h1> <p>{post.author}</p> </div> ); }
以下是我们如何使用 use() 钩子以更少的代码行完成同样的事情,消除了使用 usestate 和 useeffect 钩子来获取数据、加载状态和错误状态的需要,同时仍然实现资源缓存以改进表演。
// modern approach with use() function userprofilepost{ postid }: { postid: string }) { const post= use(fetchuserpost(postid)); return ( <suspense fallback=<loading />> <div> <errorboundary fallback=<error />> <h1>{post.title}</h1> <p>{post.author}</p> </errorboundary> </div> </suspense> ); }
现在让我们看另一个稍微复杂一点的示例。
// form submission with loading states // traditional approach using usestate and useeffect function submitformtraditional() { const [issubmitting, setissubmitting] = usestate(false); const [error, seterror] = usestate<error | null>(null); const [success, setsuccess] = usestate(false); async function handlesubmit(formdata: formdata) { setissubmitting(true); seterror(null); setsuccess(false); try { await fetch('localhost:3000/api/submit', { method: 'post', body: formdata }); setsuccess(true); } catch (err: any) { seterror(err); } finally { setissubmitting(false); } } return ( <form onsubmit={e => { e.preventdefault(); handlesubmit(new formdata(e.currenttarget)); }}> {/* form fields */} <button disabled={issubmitting}> {issubmitting ? 'submitting…' : 'submit'} </button> {error && <div><error /></div>} {success && <div><success /></div>} </form> ); }
下面是我们如何使用 use() 钩子做同样的事情。
// modern approach with use() async function submitform(formdata: formdata) { const response = await fetch('localhost:3000/api/submit', { method: 'post', body: formdata }); return response.json(); } function submitform() { const [formstate, setformstate] = usestate<promise<any> | null>(null); return ( <form onsubmit={e => { e.preventdefault(); setformstate(submitform(new formdata(e.currenttarget))); }}> {/* form fields */} <button>submit</button> {formstate && ( <suspense fallback={<div>submitting…</div>}> <formresult promise={formstate} /> </suspense> )} </form> ); } function formresult({ promise }: { promise: promise<any> }) { const result = use(promise); return <div>submitted successfully: {result.id}</div>; }
use() 钩子方法的主要区别和优点:
1. 简化的代码结构
还记得所有那些加载、错误和数据的状态变量吗?使用 use() 后,它们就消失了。您的组件变得更加简洁和直接。这不仅仅是编写更少的代码,而是编写更易于维护、可读的代码,以更好地表达您的意图。 use() 钩子消除了手动编排加载状态和错误处理的需要,减少了管理异步操作的认知开销。
2.更好的错误处理
分散的 try-catch 块和手动错误状态管理的日子已经一去不复返了。使用 use(),错误处理通过错误边界变得声明性:
errorboundary fallback={<errorstate />}> <userprofile userid={1} /> </errorboundary>
此方法可确保整个应用程序中错误处理的一致性,并使错误恢复更加可预测和可管理。
3. 自动加载状态
还记得玩弄加载标志吗? use() 钩子与 suspense 结合,自动处理这个问题:
<Suspense fallback={<LoadingSpinner />}> <UserProfile userId={123} /> </Suspense>
这种加载状态的声明性方法可以更轻松地在应用程序中创建一致的加载体验。
结论
use() 钩子代表了 react 处理异步操作的重要一步。虽然它需要我们对应用程序的思考和结构进行一些调整,但更干净的代码、更好的错误处理和改进的加载状态的好处使其成为 react 工具包中引人注目的补充。
通过采用这种新模式,我们可以编写更可维护、更高性能的应用程序,并且减少样板文件和潜在错误。随着 react 生态系统继续围绕这个新范式发展,我们可以期待看到更强大的模式和实践的出现。
请记住,虽然 use() 挂钩可能看起来是一个巨大的变化,但它最终是为了让我们作为开发人员的生活更轻松,让我们的应用程序变得更好。无论您是开始一个新项目还是维护现有项目,理解和采用这种模式对于现代 react 开发都至关重要。
注意:我不建议在生产中使用它,因为它仍处于实验阶段,因此在未来的更新中正式采用 react 之前,我不会在生产中使用它,但它很适合用于个人项目。
您对 use() 挂钩有何看法?您开始在项目中使用它了吗?在下面的评论中分享您的经验和想法!
好了,本文到此结束,带大家了解了《我对 use() 钩子的思考——深入探讨 React 的最新实验功能》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
482 收藏
-
205 收藏
-
396 收藏
-
165 收藏
-
308 收藏
-
202 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习