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