当前位置: > Linux新闻 >

React v19 正式发布

时间:2024-12-06 21:21来源:linux.it.net.cn 作者:IT
React v19 稳定版现已正式发布。为了帮助用户更轻松地升级到 React 19,项目发布了与 18.2 相同的 react@18.3 版本,但添加了针对弃用 API 和 React 19 所需的其他更改的警告。官方建议先升级到 React 18.3.1,以帮助在升级到 React 19 之前识别问题。

一些更新内容具体包括:

Actions
在 React 19 中,添加了在转换中使用异步函数的支持,以自动处理待处理状态、错误、表单和乐观更新。例如,用户可以使用 useTransition 来处理待处理状态:

// Using pending state from Actions
function UpdateName({}) {
  const [name, setName] = useState("");
  const [error, setError] = useState(null);
  const [isPending, startTransition] = useTransition();

  const handleSubmit = () => {
    startTransition(async () => {
      const error = await updateName(name);
      if (error) {
        setError(error);
        return;
      }
      redirect("/path");
    })
  };

  return (
    <div>
      <input value={name} onChange={(event) => setName(event.target.value)} />
      <button onClick={handleSubmit} disabled={isPending}>
        Update
      </button>
      {error && <p>{error}</p>}
    </div>
  );
}
异步转换将立即将 isPending 状态设置为 true,发出异步请求,并在任何转换完成后将isPending切换回false。这样就可以在数据变更时保持当前 UI 的响应性和交互性。

在 Actions 的基础上,React 19 引入了 useOptimistic管理乐观更新的功能,以及一个全新的 Hook React.useActionState 用于处理常见的 Actions 场景。在 react-dom 中,添加了 <form> Actions 来自动管理表单,以及 useFormStatus 来支持表单中常见的 Actions 场景。

// Using <form> Actions and useActionState
function ChangeName({ name, setName }) {
  const [error, submitAction, isPending] = useActionState(
    async (previousState, formData) => {
      const error = await updateName(formData.get("name"));
      if (error) {
        return error;
      }
      redirect("/path");
      return null;
    },
    null,
  );

  return (
    <form action={submitAction}>
      <input type="text" name="name" />
      <button type="submit" disabled={isPending}>Update</button>
      {error && <p>{error}</p>}
    </form>
  );
}
新 Hook:useActionState
为了更简单的处理常见的 Actions 场景,添加了一个新的 Hook,称为 useActionState:

const [error, submitAction, isPending] = useActionState(
  async (previousState, newName) => {
    const error = await updateName(newName);
    if (error) {
      // You can return any result of the action.
      // Here, we return only the error.
      return error;
    }

    // handle success
    return null;
  },
  null,
);
useActionState 接受一个函数(“Action”),并返回一个包装后的 Action 以供调用。当调用包装后的 Action 时,useActionState将返回Action的最后结果作为data,并返回Action的等待状态作为pending。

值得注意的是,在 Canary 版本中,React.useActionState以前被称为ReactDOM.useFormState,现在已将其重命名并弃用了useFormState。可参阅#28491 以了解更多信息。

React DOM: <form> Actions
在 React 19 中,Actions 被集成到了react-dom新引入的<form>功能中。现在支持将函数作为<form>、<input>和<button>元素的action和formAction属性传递,以使用 Actions 自动提交表单:

<form action={actionFunction}>
当 <form>Action 成功执行时,React 会自动重置不受控组件的表单。如果需要手动重置 <form>,可以调用新的 React DOM APIrequestFormReset。

React DOM: New hook: useFormStatus
在设计系统中,通常需要编写设计组件,这些组件需要获取其所处 <form> 表单的相关信息,但又不想通过 props 逐级向下传递。虽然可以通过 Context 来实现这一点,但为了让这种常见情况更简单,React 19 添加了一个新 hookuseFormStatus:

import {useFormStatus} from 'react-dom';

function DesignButton() {
  const {pending} = useFormStatus();
  return <button type="submit" disabled={pending} />
}
useFormStatus可以读取父级<form> 的状态,就好像该表单是一个 Context 提供者一样。

新 hook:useOptimistic
执行数据变更时的另一个常见 UI 模式是在异步请求进行时乐观地显示最终状态。在 React 19 中添加了一个新的 hookuseOptimistic 以使此操作更容易:

function ChangeName({currentName, onUpdateName}) {
  const [optimisticName, setOptimisticName] = useOptimistic(currentName);

  const submitAction = async formData => {
    const newName = formData.get("name");
    setOptimisticName(newName);
    const updatedName = await updateName(newName);
    onUpdateName(updatedName);
  };

  return (
    <form action={submitAction}>
      <p>Your name is: {optimisticName}</p>
      <p>
        <label>Change Name:</label>
        <input
          type="text"
          name="name"
          disabled={currentName !== optimisticName}
        />
      </p>
    </form>
  );
}
该 hook 将在 updateName 请求过程中立即渲染 optimisticName。当更新完成或出现错误时,React 将自动切换回 currentName 值。

New API: use
在 React 19 中,引入了一个新 API 来在渲染过程中读取资源:use。例如,可以使用 use 来读取一个 Promise,React 将挂起,直到 promise 成功解析:

import {use} from 'react';

function Comments({commentsPromise}) {
  // `use` will suspend until the promise resolves.
  const comments = use(commentsPromise);
  return comments.map(comment => <p key={comment.id}>{comment}</p>);
}

function Page({commentsPromise}) {
  // When `use` suspends in Comments,
  // this Suspense boundary will be shown.
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Comments commentsPromise={commentsPromise} />
    </Suspense>
  )
}
还可以使用use来读取 Context,这使得你可以有条件地读取 Context,例如在提前返回之后读取:

import {use} from 'react';
import ThemeContext from './ThemeContext'

function Heading({children}) {
  if (children == null) {
    return null;
  }
 
  // This would not work with useContext
  // because of the early return.
  const theme = use(ThemeContext);
  return (
    <h1 style={{color: theme.color}}>
      {children}
    </h1>
  );
}
该 useAPI 只能在渲染中调用,类似于 hooks。与 hooks 不同,use 可以有条件地调用。项目团队未来计划使用 use 支持更多在渲染中使用资源的方式。有关详细信息,可参阅文档 use。

新的 React DOM 静态 API
为 react-dom/static 添加了两个用于静态站点生成的新 API:

prerender
prerenderToNodeStream
这两个新的 API 通过等待数据加载以生成静态 HTML 来改进了renderToString。它们旨在与 Node.js Streams 和 Web Streams 等流式环境配合使用。例如,在 Web Stream 环境中,可以使用prerender将 React 组件树预渲染为静态 HTML:

import { prerender } from 'react-dom/static';

async function handler(request) {
  const {prelude} = await prerender(<App />, {
    bootstrapScripts: ['/main.js']
  });
  return new Response(prelude, {
    headers: { 'content-type': 'text/html' },
  });
}
Prerender API 将等待所有数据加载完毕后再返回静态 HTML 流。流可以转换为字符串,或通过流式响应发送。它们不支持在加载时流式传输内容,而现有的 React DOM 服务端渲染 API 则支持此功能。可参阅 React DOM 静态 API。

更多详情可查看官方公告。


(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容