React 19 特性

2024-05-17

使用useTransition来自动处理挂起状态

异步转换会立刻将isPending状态设为true,发起异步请求,并在转换完成后将isPending设置为false。这样可以确保数据变化时,UI 仍然保持响应和交互性。

function UpdateName({}) {
  const [name, setName] = useState("");
  const [error, setError] = useState(null);
  const [isPending, startTransition] = useTransition();

  const handleSubmit = async () => {
    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>
  );
}

useActionState, useFormStatus, useOptimistic

新增了 useActionState 来自动管理表单操作,并提供了 useFormStatus 来支持表单中 Actions 的常见需求。

useActionState

useActionState将返回Action的最后一个结果作为数据,并将Action的挂起状态作为pending返回。

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 (
    <form action={submitAction}>
      <input type="text" name="name" />
      <button type="submit" disabled={isPending}>Update</button>
      {error && <p>{error}</p>}
    </form>
  );
}

useFormStatus

useFormStatus可以读取父级的状态,就像该表单是一个Contextprovider 一样。

useOptimistic

在数据变更操作中,一种常见的 UI 模式是在异步请求执行期间乐观地显示预期的最终状态。

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>
  );
}

useOptimistic Hook 允许在updateName请求还在进行时,立即将输入框的值(即newName)设置为optimisticName,从而乐观地更新UI。如果更新成功,则通过onUpdateName回调函数来确认状态的更改;如果更新失败或发生错误,可以通过setOptimisticName回滚到原始状态currentName。

use

允许在组件渲染时直接读取资源。

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

function Heading({children}) {
  if (children == null) {
    return null;
  }
   
  // 使用 useContext 在这里不会生效 ,因为存在早期返回。
  const theme = use(ThemeContext);
  return (
    <h1 style={{color: theme.color}}>
      {children}
    </h1>
  );
}

use API 的调用仅限于渲染阶段,与 React 的 Hook 类似。然而,与 Hook 不同的是,use API 允许在条件语句中灵活调用。展望未来,React 团队计划进一步扩展 use API 的功能,提供更多在渲染时消费资源的方式。

服务器组件

服务器组件是一种创新性的技术,它允许在打包前,在独立于客户端应用程序或服务器端渲染(SSR)服务器的环境中预先渲染组件。这个独立的环境即为React服务器组件中的“服务器”。服务器组件有两种运行模式:一种是在构建时(例如在持续集成服务器上)运行一次;另一种是针对每个请求,通过 Web 服务器进行实时运行。

功能改进

作为提供者

React 19 允许直接将 用作提供者,而无需使用传统的 <Context.Provider> 写法:

const ThemeContext = createContext('');  
  
function App({children}) {  
  return (  
    <ThemeContext value="dark">  
      {children}  
    </ThemeContext>  
  );  
}
copyright ©2019-2024 shenzhen
粤ICP备20041170号-1