lesenelir / read

Logging tech articles and tools I've used.
MIT License
0 stars 0 forks source link

React 19 Beta #5

Open lesenelir opened 4 months ago

lesenelir commented 4 months ago

https://react.dev/blog/2024/04/25/react-19

lesenelir commented 4 months ago

React 19 Beta

  1. Actions

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 会去做新的更新,这时候就自动解决了数据请求的竞态条件。

  1. useOptimistic

乐观更新和 server action 一起用。乐观更新会立即反映用户的操作结果,而不等服务端确认操作成功。

这种方法基于一个假设:大多数操作最终都会成功。如果失败的话,再撤回更新(state回滚)并通知用户失败。

  1. use

利用 use 来读取一个 Promise,会触发 Suspense 边界,reject promise 会触发 Error Boundary。

比如或许可以用 use 来进行数据的请求。

  1. RSC

单独脱离 client app 和 ssr server,提前渲染 UI。这个单独的环境是 React server component 中的服务器。

RSC 可以在服务器 build time 的时候在 服务器上运行一次,之后都复用这个结果(RSC Payload);也可以针对每个请求来跑 RSC,不同的 RSC Payload 可能不同。所以 RSC 部署后可能不需要服务器。

  1. Server Action

略略略~~

  1. ref props

ref 可以作为prosp,ref 转发的时候可以舍弃 forwardRef api。

  1. Context as provider
==> 。无所谓吧,反正也不用 context 8. ref callback 现在 ref callback 可以有 clearnup function 。当元素从 dom 卸载的时候会去调用这个 cleanup function 9. useDeferredValue initialValue `useDeferredValue(value, initialValue?)`` 10. Document Metadata React 组件原生就支持了 metadata tags 。组件渲染的时候,如果看到这些 metadata tags 就会将这些标签元素自动覆盖到 head 标签中。 支持所有组件:RCC、RSC、Suspense SSR