Open lesenelir opened 4 months ago
React 19 Beta
transition update 过渡更新,startTransition(fn) fn 现在可以是一个 async function。
// 原有:
const handleSubmit = async () => {
setIsPending(true);
const error = await updateName(name);
setIsPending(false);
if (error) {
setError(error);
return;
}
redirect("/path");
};
// 现在:
const [isPending, startTransition] = useTransition()
const handleSubmit = () => {
startTransition(async () => {
const error = await updateName(name); // api request
if (error) {
setError(error);
return;
}
redirect("/path");
})
};
此时的这个 api 请求所有相关的 state 更新(异步请求相关的 state 更新)都从原来的 urgent update 变为了 transition update。发出请求的时候 isPending 值为 true,拿到数据后立即为 false。
这是对原有 concurrent mode 的一个扩展。在此之前,只有同步的 state 更新才能变为 transition update ,现在异步任务更新的 state 也可以变为 transition update 。
至于为什么要这么做,主要原因还是 React 引入 Concurrent Rendering 的原因一致。浏览器的主线程是单线程,当 state 更新 re-render 占据主线程时,浏览器就无法进行布局、绘制、响应用户交互。 当有大量的 state 更新,整个页面都会被卡住(尤其是进行复杂计算的 state 更新),用户无法和页面进行交互。这也是为什么引入 Concurrent Rendering 的原因
现在将数据state 更新转变为 transition update,有两个好处。一,可以使得数据 state 更新的时候,UI 还是可交互的;二,当前 state 更新是低优先级的,如果有更高优先级的 state 更新会先去触发,比如新 state 更新后有新的请求,则transition update 会去做新的更新,这时候就自动解决了数据请求的竞态条件。
乐观更新和 server action 一起用。乐观更新会立即反映用户的操作结果,而不等服务端确认操作成功。
这种方法基于一个假设:大多数操作最终都会成功。如果失败的话,再撤回更新(state回滚)并通知用户失败。
利用 use 来读取一个 Promise,会触发 Suspense 边界,reject promise 会触发 Error Boundary。
比如或许可以用 use 来进行数据的请求。
单独脱离 client app 和 ssr server,提前渲染 UI。这个单独的环境是 React server component 中的服务器。
RSC 可以在服务器 build time 的时候在 服务器上运行一次,之后都复用这个结果(RSC Payload);也可以针对每个请求来跑 RSC,不同的 RSC Payload 可能不同。所以 RSC 部署后可能不需要服务器。
略略略~~
ref 可以作为prosp,ref 转发的时候可以舍弃 forwardRef api。
https://react.dev/blog/2024/04/25/react-19