1、useActionState 方便表单操作
import React, { useState } from 'react';
// 自定义 Hook:useActionState
function useActionState() {
const [isLoading, setIsLoading] = useState(false);
const startAction = () => setIsLoading(true);
const endAction = () => setIsLoading(false);
return [isLoading, startAction, endAction];
}
function ActionButton() {
const [isLoading, startAction, endAction] = useActionState();
const handleClick = async () => {
startAction();
// 模拟一个异步操作
await new Promise((resolve) => setTimeout(resolve, 2000));
endAction();
};
return (
<div>
<button onClick={handleClick} disabled={isLoading}>
{isLoading ? '加载中...' : '点击执行操作'}
</button>
</div>
);
}
export default ActionButton;
2、useFormStatus 帮助控制表单的整体状态
import React, { useState } from 'react';
// 自定义 Hook:useFormStatus
function useFormStatus() {
const [isSubmitting, setIsSubmitting] = useState(false); // 表单是否正在提交
const [isValid, setIsValid] = useState(true); // 表单是否有效
const [errors, setErrors] = useState({}); // 存储错误信息
const startSubmit = () => {
setIsSubmitting(true); // 开始提交
};
const endSubmit = () => {
setIsSubmitting(false); // 提交结束
};
const setFormErrors = (errorObj) => {
setErrors(errorObj); // 设置错误信息
};
const setFormValid = (valid) => {
setIsValid(valid); // 设置表单有效性
};
return { isSubmitting, isValid, errors, startSubmit, endSubmit, setFormErrors, setFormValid };
}
function MyForm() {
const { isSubmitting, isValid, errors, startSubmit, endSubmit, setFormErrors, setFormValid } = useFormStatus();
const handleSubmit = async (e) => {
e.preventDefault();
startSubmit();
// 假设表单验证过程
const formErrors = {};
const formData = new FormData(e.target);
if (!formData.get('username')) {
formErrors.username = '用户名不能为空';
}
if (!formData.get('password')) {
formErrors.password = '密码不能为空';
}
if (Object.keys(formErrors).length > 0) {
setFormErrors(formErrors);
setFormValid(false);
endSubmit();
return;
}
// 模拟一个异步提交操作
await new Promise((resolve) => setTimeout(resolve, 2000));
endSubmit();
alert('表单提交成功');
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="username">用户名:</label>
<input type="text" id="username" name="username" />
{errors.username && <p style={{ color: 'red' }}>{errors.username}</p>}
</div>
<div>
<label htmlFor="password">密码:</label>
<input type="password" id="password" name="password" />
{errors.password && <p style={{ color: 'red' }}>{errors.password}</p>}
</div>
<div>
<button type="submit" disabled={isSubmitting || !isValid}>
{isSubmitting ? '提交中...' : '提交'}
</button>
</div>
</form>
);
}
export default MyForm;
3、useOptimistic 乐观更新
用户触发某些操作时,立即在界面上反映结果,而无需等待服务器响应。如果操作失败,再回滚到之前的状态。
import React, { useState } from 'react';
// 假设这是一个异步 API 请求函数
const mockApiRequest = (newLikes) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > 0.2 ? resolve(newLikes) : reject(new Error('点赞失败'));
}, 1000);
});
};
function useOptimistic(initialState) {
const [state, setState] = useState(initialState);
const [backup, setBackup] = useState(initialState);
const optimisticUpdate = (updater, rollback) => {
setBackup(state); // 保存当前状态以便回滚
const updatedState = updater(state);
setState(updatedState);
return async (action) => {
try {
await action(updatedState); // 执行实际操作
} catch (error) {
setState(rollback(backup)); // 操作失败,回滚状态
throw error;
}
};
};
return [state, optimisticUpdate];
}
function LikeButton() {
const [likes, optimisticUpdate] = useOptimistic(0);
const handleLike = async () => {
const executeAction = optimisticUpdate(
(currentLikes) => currentLikes + 1,
(previousLikes) => previousLikes
);
try {
await executeAction(() => mockApiRequest(likes + 1));
console.log('点赞成功');
} catch (error) {
console.error(error.message);
}
};
return (
<button onClick={handleLike}>
点赞 {likes}
</button>
);
}
export default LikeButton;
4、支持的 metadata tags
import React from 'react';
import { MetadataProvider, Title, Meta, Link } from '@react/metadata';
function HomePage() {
return (
<>
<Title>首页 - 我的网站</Title>
<Meta name="description" content="这是我的网站首页,包含关于 React 19 的新特性介绍。" />
<Meta name="keywords" content="React 19, Metadata Tags, 新特性" />
<Link rel="canonical" href="https://www.mywebsite.com/" />
<h1>欢迎来到我的网站</h1>
<p>探索 React 19 中的新特性!</p>
</>
);
}
function AboutPage() {
return (
<>
<Title>关于我们 - 我的网站</Title>
<Meta name="description" content="了解更多关于我们团队的信息。" />
<Meta name="keywords" content="关于我们, React 19, Metadata Tags" />
<Link rel="canonical" href="https://www.mywebsite.com/about" />
<h1>关于我们</h1>
<p>我们是一支专注于现代 Web 开发的团队。</p>
</>
);
}
function App() {
return (
<MetadataProvider>
{/* 模拟路由切换 */}
<HomePage />
{/* 替换为 <AboutPage /> 可观察元数据的变化 */}
</MetadataProvider>
);
}
export default App;
5、资源加载改进
例子:首屏预加载
import React from 'react';
function HomePage() {
return (
<div>
<h1>Welcome to React 19!</h1>
<img
src="hero.jpg"
alt="Hero"
width="800"
height="400"
loading="eager"
/>
</div>
);
}
export default HomePage;
6、Web 组件支持
示例:使用 Web Components 与 React 集成
定义一个 Web Component
// custom-button.js
class CustomButton extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const button = document.createElement('button');
button.textContent = this.getAttribute('label') || 'Click me';
button.addEventListener('click', () => {
const event = new CustomEvent('onCustomClick', {
detail: { message: 'Button clicked!' },
});
this.dispatchEvent(event);
});
shadow.appendChild(button);
}
}
customElements.define('custom-button', CustomButton);
在 React 中使用 Web Component
import React from 'react';
import './custom-button.js'; // 引入 Web Component 定义
function App() {
const handleCustomClick = (event) => {
alert(event.detail.message);
};
return (
<div>
<h1>React 19 Web Components Support</h1>
<custom-button
label="Click Me"
onCustomClick={handleCustomClick}
></custom-button>
</div>
);
}
export default App;