React 19 于2024年12月正式发布,带来了许多重要功能和改进。这次更新延续了 React 团队专注于提升开发体验和性能的目标,引入了多项新特性,使 React 应用开发变得更加简单和高效。

主要新功能

Actions

React 19引入了”Actions”的概念,这是一个重要的数据突变处理模式。在以前的版本中,当用户提交表单或执行数据修改操作时,开发者需要手动处理等待状态(pending states)、错误处理、乐观更新和连续请求等问题。

例如,在React 19之前,处理表单提交需要这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Before Actions
function UpdateName({}) {
const [name, setName] = useState('');
const [error, setError] = useState(null);
const [isPending, setIsPending] = useState(false);
const handleSubmit = async () => {
setIsPending(true);
const error = await updateName(name);
setIsPending(false);
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>
);
}

在React 19中,通过使用异步转换(Actions),可以自动处理这些状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 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>
);
}

Actions自动管理以下方面:

  • 待定状态(Pending state):在请求开始时自动设置待定状态,并在最终状态更新提交后自动重置
  • 乐观更新:支持useOptimistic钩子,可在请求提交期间向用户提供即时反馈
  • 错误处理:提供错误处理功能,可以在请求失败时显示错误边界,并自动将乐观更新恢复到原始值
  • 表单:
    元素现在支持将函数传递给action和formAction属性

useActionState 钩子

为了简化 Actions 的常见用法,React 19 引入了 useActionState 钩子:

1
2
3
4
5
6
7
8
9
10
const [error, submitAction, isPending] = useActionState(async (previousState, newName) => {
const error = await updateName(newName);
if (error) {
// 可以返回操作的任何结果
// 这里,我们只返回错误
return error;
}
// 处理成功情况
return null;
}, null);

React DOM 中的表单 Actions

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

1
<form action={actionFunction}>

当表单 Action 成功时,React 将自动为非受控组件重置表单。

useFormStatus 钩子

在设计系统中,通常需要编写需要访问其所在表单信息的设计组件,而不需要将 props 层层传递下去。为此,React 19 引入了 useFormStatus 钩子:

1
2
3
4
5
6
import { useFormStatus } from 'react-dom';

function DesignButton() {
const { pending } = useFormStatus();
return <button type='submit' disabled={pending} />;
}

useOptimistic 钩子

另一个常见的 UI 模式是在执行数据变更时,在异步请求进行的同时显示最终状态。React 19 引入了 useOptimistic 钩子来简化这一过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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>
);
}

use API

React 19 引入了新的 use API 来读取渲染中的资源。例如,可以使用 use 读取 Promise,React 将暂停直到 Promise 解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { use } from 'react';
function Comments({ commentsPromise }) {
// `use`将暂停直到Promise解析
const comments = use(commentsPromise);
return comments.map(comment => <p key={comment.id}>{comment}</p>);
}
function Page({ commentsPromise }) {
// 当Comments中的`use`暂停时,
// 将显示此Suspense边界
return (
<Suspense fallback={<div>Loading...</div>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
);
}

use API 还可以读取上下文,允许有条件地读取 Context,例如在早期返回之后:

1
2
3
4
5
6
7
8
9
10
11
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>;
}

重要改进

React编译器

React 19 的明星功能是新的 React 编译器。这个编译器将 React 代码转换为纯 JavaScript,提升性能,并免除手动优化的麻烦。编译器能够自动优化重新渲染,减少手动使用 useMemo、useCallback 和 memo API的需求。

性能改进

React 19 引入了新的性能优化,包括对 React 组件和 React DOM 的优化。这些改进包括:

  • 更好的并发渲染
  • 改进的协调算法
  • 选择性水合(Selective hydration)
  • 预热暂停树(Pre-warming for suspended trees)

服务器端渲染(SSR)改进

React 19 增强了服务器端渲染功能,包括:

  • 更好的Web Streams支持
  • 改进的水合过程
  • 更快的初始加载时间

错误处理改进

React 19 改进了错误处理机制,包括改进的错误信息和错误处理方式。引入了新的错误处理方法,使调试更加容易。

静态API改进

React 19 引入了新的 React DOM 静态API,这些 API 有助于在构建时预渲染应用的部分内容。

迁移注意事项

React 19 引入了一些重大变更,需要注意:

  1. JSX 转换要求:React 19 强制使用新的 JSX 转换
  2. 旧版 API 删除:ReactDOM.renderReactDOM.hydrate 等API已被删除,替换为 ReactDOM.createRootReactDOM.hydrateRoot
  3. 错误处理变化:React 19 引入了新的错误处理方法

总结

React 19 是一个重要的更新,它专注于简化开发过程并提升性能。通过引入 Actions、新的 Hooks 和改进的 API,React 19 使得数据突变处理、表单管理和状态管理变得更加直观和高效。

此外,React 编译器的引入标志着 React 在自动优化方面的重大进步,有望显著提升应用性能,同时减少开发者手动优化的工作量。

总的来说,React 19 继续贯彻了 React 团队的承诺——在不增加复杂性的情况下提供更多功能,让开发者能够构建更高效、更可靠的 Web 应用程序。