
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 hello, {user.name}!;
}
use() 钩子代表了 react 处理异步数据方式的重大转变,使其更加直观并降低了管理异步状态的复杂性。
use() 钩子的主要特点:
promise 处理:use() 可以处理组件中任何级别的 promise。它会在等待 promise 解决时自动挂起组件,并且与 react 的 suspense 边界配合使用。
错误处理更直观:
try {
const data = use(riskyoperation());
return ;
} catch (error) {
return ;
}
- 资源缓存: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(null);
const [isloading, setisloading] = usestate(true);
const [error, seterror] = usestate(null);
useeffect(() => {
setisloading(true);
seterror(null);
fetchuserposts(userid)
.then(data => {
setpost(data);
})
.catch(err => {
seterror(err);
})
.finally(() => {
setisloading(false);
});
}, [userid]);
if (isloading) return ;
if (error) return ;
if (!post) return null;
return (
{post.title}
{post.author}
);
}
以下是我们如何使用 use() 钩子以更少的代码行完成同样的事情,消除了使用 usestate 和 useeffect 钩子来获取数据、加载状态和错误状态的需要,同时仍然实现资源缓存以改进表演。
// modern approach with use()
function userprofilepost{ postid }: { postid: string }) {
const post= use(fetchuserpost(postid));
return (
>
>
{post.title}
{post.author}
);
}
现在让我们看另一个稍微复杂一点的示例。
// form submission with loading states
// traditional approach using usestate and useeffect
function submitformtraditional() {
const [issubmitting, setissubmitting] = usestate(false);
const [error, seterror] = usestate(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 (
);
}
下面是我们如何使用 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 | null>(null);
return (










