本文档为 React 19.1 的全面使用指南,涵盖核心功能、新特性、TypeScript 集成及最佳实践。每个知识点都附带详细代码示例,适用于初学者和高级开发者。React 19 引入了多项突破性特性,如 React 编译器、Server Components、Server Actions 和新 Hooks,旨在简化开发、提升性能和优化用户体验。本文档基于官方文档和其他可靠资源(如 React Conf 2024 和 freeCodeCamp)编写。
1. 安装与配置
1.1 安装 React 19
React 19 可通过 npm 安装,推荐在项目中局部安装以确保版本一致性。
npm install react@19.1 react-dom@19.1
TypeScript 用户:确保安装最新类型定义:
npm install --save-dev @types/react@19.0 @types/react-dom@19.0
1.2 配置项目
React 19 要求使用新的 JSX 转换,推荐与 Vite 或 Next.js 等现代构建工具配合。以下是一个 Vite 项目的基本配置:
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
build: {
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes("node_modules")) {
return "vendor";
}
},
},
},
},
});
tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"jsx": "react-jsx",
"moduleResolution": "node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"baseUrl": "src",
"paths": {
"@components/*": ["components/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
说明:
"jsx": "react-jsx"
启用新的 JSX 转换,取代React.createElement
。"strict": true
确保类型安全。paths
配置模块别名,简化导入。
2. 核心概念
2.1 组件(Components)
React 19 支持函数组件和类组件,但推荐使用函数组件与 Hooks。
示例:函数组件
import React from "react";
interface Props {
name: string;
}
const Greeting: React.FC<Props> = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
export default Greeting;
使用
import Greeting from "@components/Greeting";
const App: React.FC = () => {
return <Greeting name="Alice" />;
};
2.2 Props 与 State
Props 用于父子组件通信,State 用于管理组件内部状态。
示例:State 管理
import React, { useState } from "react";
const Counter: React.FC = () => {
const [count, setCount] = useState<number>(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
最佳实践:
- 使用 TypeScript 定义 Props 和 State 类型。
- 避免过多的 State,优先使用派生状态。
- 对于复杂状态管理,考虑
useReducer
或 Zustand。
3. React 19 新特性
3.1 React 编译器
React 19 引入了开源 React 编译器(React Fizz),自动优化组件渲染,消除手动使用 useMemo
和 useCallback
的需求。
示例:无需手动优化的组件
import React from "react";
interface Item {
id: number;
name: string;
}
const ItemList: React.FC<{ items: Item[] }> = ({ items }) => {
// 无需 useMemo 或 useCallback,编译器自动优化
const filteredItems = items.filter((item) => item.id > 0);
return (
<ul>
{filteredItems.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
};
说明:
- 编译器将 JSX 转换为优化的 JavaScript,减少不必要的重新渲染。
- 需要安装
babel-plugin-react-compiler
:
babel.config.js
const ReactCompilerConfig = {
sources: (filename: string) => filename.includes("src/components"),
};
module.exports = {
plugins: [["babel-plugin-react-compiler", ReactCompilerConfig]],
};
最佳实践:
- 在项目中逐步启用编译器,先在非关键目录测试。
- 确保代码符合编译器要求(如避免动态依赖)。
3.2 Server Components
Server Components 允许在服务器上渲染组件,减少客户端 JavaScript 量,提升性能和 SEO。
示例:Server Component
// server/HomePage.server.tsx
import { db } from "../db";
async function HomePage() {
const posts = await db.posts.findMany();
return (
<div>
<h1>Latest Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
export default HomePage;
说明:
- 使用
"use server"
指令定义 Server Components 或 Server Actions。 - Server Components 不能包含客户端交互逻辑(如
useState
)。 - 需要配合支持 Server Components 的框架(如 Next.js 15)。
最佳实践:
- 将数据获取逻辑放在 Server Components 中。
- 使用 Client Components 处理交互逻辑。
- 确保 Server Components 不依赖客户端 API(如
window
)。
3.3 Server Actions
Server Actions 允许 Client Components 调用服务器上的异步函数,简化数据操作。
示例:Server Action
// server/actions.ts
"use server";
import { db } from "../db";
export async function createTodo(formData: FormData) {
const title = formData.get("title") as string;
await db.todos.create({ title });
}
使用 Server Action
// client/TodoForm.tsx
import { useActionState } from "react";
import { createTodo } from "../server/actions";
const TodoForm: React.FC = () => {
const [state, dispatch, isPending] = useActionState(createTodo, null);
return (
<form action={dispatch}>
<input type="text" name="title" disabled={isPending} />
<button type="submit" disabled={isPending}>
{isPending ? "Creating..." : "Create Todo"}
</button>
{state?.message && <p>{state.message}</p>}
</form>
);
};
说明:
useActionState
管理表单提交状态,自动处理 pending 状态和错误。- Server Actions 需在支持的框架中配置(如 Next.js)。
最佳实践:
- 使用 TypeScript 验证
formData
的类型。 - 提供用户反馈(如 loading 状态或错误信息)。
- 避免在 Server Actions 中执行复杂逻辑,保持单一职责。
3.4 新 Hooks
3.4.1 useOptimistic
useOptimistic
用于乐观更新,提供即时 UI 反馈。
示例:乐观更新
import React, { useState, useOptimistic } from "react";
import { createTodo } from "../server/actions";
const OptimisticTodo: React.FC = () => {
const [todos, setTodos] = useState<string[]>([]);
const [optimisticTodos, addOptimisticTodo] = useOptimistic(
todos,
(state, newTodo: string) => [...state, newTodo]
);
const handleSubmit = async (formData: FormData) => {
const title = formData.get("title") as string;
addOptimisticTodo(title);
await createTodo(formData);
setTodos((prev) => [...prev, title]);
};
return (
<form action={handleSubmit}>
<input type="text" name="title" />
<button type="submit">Add Todo</button>
<ul>
{optimisticTodos.map((todo, index) => (
<li key={index}>{todo}</li>
))}
</ul>
</form>
);
};
说明:
useOptimistic
在服务器响应前显示临时状态。- 实际响应返回后,状态会同步更新。
最佳实践:
- 用于低风险操作(如添加评论、点赞)。
- 确保服务器操作与乐观更新逻辑一致。
3.4.2 useFormStatus
useFormStatus
提供表单提交状态,简化表单管理。
示例:表单状态
import React, { useFormStatus } from "react";
const SubmitButton: React.FC = () => {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? "Submitting..." : "Submit"}
</button>
);
};
const Form: React.FC = () => {
return (
<form action="/api/submit">
<input type="text" name="name" />
<SubmitButton />
</form>
);
};
最佳实践:
- 将
useFormStatus
用于子组件,避免 prop 钻透。 - 结合
useActionState
提供完整的表单体验。
3.4.3 use
use
Hook 用于读取 Promise 或上下文,集成 Suspense。
示例:数据获取
import React, { use, Suspense } from "react";
interface Comment {
id: number;
text: string;
}
const Comments: React.FC<{ commentsPromise: Promise<Comment[]> }> = ({
commentsPromise,
}) => {
const comments = use(commentsPromise);
return (
<ul>
{comments.map((comment) => (
<li key={comment.id}>{comment.text}</li>
))}
</ul>
);
};
const Page: React.FC = () => {
const commentsPromise = fetch("https://api.example.com/comments").then(
(res) => res.json()
);
return (
<Suspense fallback={<div>Loading...</div>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
);
};
说明:
use
暂停渲染直到 Promise 解析,需配合Suspense
。- 适合 Server Components 或流式渲染。
最佳实践:
- 始终用
Suspense
包裹use
调用。 - 提供友好的加载 UI。
3.5 Document Metadata
React 19 支持在组件中直接渲染 <title>
、<meta>
等标签,自动提升到 <head>
,简化 SEO 管理。
示例:元数据
import React from "react";
const HomePage: React.FC = () => {
return (
<>
<title>My App - Home</title>
<meta name="description" content="Welcome to my React 19 app" />
<h1>Home Page</h1>
</>
);
};
最佳实践:
- 使用
DocumentHead
组件(若框架支持)集中管理元数据。 - 确保元数据与页面内容一致,提升 SEO 效果。
3.6 Asset Loading
React 19 优化了资源(如图片、脚本、样式)加载,支持后台预加载和 Suspense。
示例:异步脚本
import React from "react";
const Analytics: React.FC = () => {
return <script async src="https://example.com/analytics.js" />;
};
说明:
- 异步脚本可渲染在组件树任意位置,React 自动去重并优化加载。
最佳实践:
- 使用
preload
和prefetch
API 优化关键资源。 - 结合
Suspense
管理资源加载状态。
4. TypeScript 集成
React 19 增强了 TypeScript 支持,推荐使用最新类型定义。
4.1 Props 类型
为 Props 定义接口,确保类型安全。
示例
interface ButtonProps {
label: string;
onClick: () => void;
disabled?: boolean;
}
const Button: React.FC<ButtonProps> = ({ label, onClick, disabled }) => {
return (
<button onClick={onClick} disabled={disabled}>
{label}
</button>
);
};
4.2 Refs
React 19 支持直接传递 ref
作为 Props,无需 forwardRef
。
示例
import React, { useRef } from "react";
const Input: React.FC<{ ref: React.RefObject<HTMLInputElement> }> = ({
ref,
}) => {
return <input ref={ref} />;
};
const App: React.FC = () => {
const inputRef = useRef<HTMLInputElement>(null);
const focusInput = () => {
inputRef.current?.focus();
};
return (
<div>
<Input ref={inputRef} />
<button onClick={focusInput}>Focus Input</button>
</div>
);
};
最佳实践:
- 使用
React.RefObject
声明 Ref 类型。 - 检查
ref.current
是否存在(strictNullChecks
)。
5. 性能优化
5.1 React 编译器
如前所述,React 编译器自动优化渲染,减少手动 memoization。
5.2 Suspense 与 Lazy Loading
使用 React.lazy
和 Suspense
实现代码分割。
示例
import React, { Suspense, lazy } from "react";
const HeavyComponent = lazy(() => import("./HeavyComponent"));
const App: React.FC = () => {
return (
<Suspense fallback={<div>Loading...</div>}>
<HeavyComponent />
</Suspense>
);
};
最佳实践:
- 对大型组件使用
React.lazy
减少初始加载时间。 - 提供清晰的加载 UI。
5.3 自动批处理
示例
import React, { useState } from "react";
const BatchUpdate: React.FC = () => {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
const handleClick = () => {
setTimeout(() => {
setCount((c) => c + 1);
setFlag((f) => !f); // React 19 仅触发一次渲染
}, 1000);
};
return <button onClick={handleClick}>Update</button>;
};
6. 错误处理
React 19 改进了错误处理,支持更清晰的错误信息和 Error Boundary。
示例:Error Boundary
import React from "react";
interface ErrorBoundaryProps {
fallback: React.ReactNode;
children: React.ReactNode;
}
interface ErrorBoundaryState {
hasError: boolean;
}
class ErrorBoundary extends React.Component<
ErrorBoundaryProps,
ErrorBoundaryState
> {
state: ErrorBoundaryState = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
console.error("Error:", error, info);
}
render() {
if (this.state.hasError) {
return this.props.fallback;
}
return this.props.children;
}
}
const App: React.FC = () => {
return (
<ErrorBoundary fallback={<h1>Something went wrong</h1>}>
<ThrowsError />
</ErrorBoundary>
);
};
最佳实践:
- 使用
onUncaughtError
和onCaughtError
捕获全局错误。 - 提供用户友好的错误 UI。
7. 最佳实践
- 使用函数组件和 Hooks:优先使用函数组件,避免类组件。
- 启用 React 编译器:在支持的环境中启用编译器以简化优化。
- TypeScript 优先:使用 TypeScript 确保类型安全,减少运行时错误。
- Server Components 与 Client Components 分离:将数据获取放在 Server Components,交互逻辑放在 Client Components。
- 模块化与代码分割:使用
React.lazy
和模块别名组织代码。 - 测试与调试:
- 使用
@testing-library/react
进行单元测试。 - 安装 React DevTools 调试组件树和性能。
- 使用
- SEO 优化:使用 Document Metadata 管理
<head>
标签。 - 渐进式升级:在非生产环境测试 React 19 新特性,逐步迁移。
- 避免过早优化:依赖 React 编译器,减少手动
useMemo
和useCallback
。 - 保持一致性:遵循 PascalCase 组件命名,kebab-case 文件命名。
8. 迁移到 React 19
8.1 关键变更
- 移除旧 API:
ReactDOM.render
和ReactDOM.hydrate
被createRoot
和hydrateRoot
取代。 - 新 JSX 转换:必须使用
react-jsx
。 - 移除
forwardRef
:直接传递ref
作为 Props。 - 废弃
react-test-renderer
:推荐使用@testing-library/react
。
8.2 迁移步骤
- 更新依赖到
react@19.1
和react-dom@19.1
。 - 运行
npx types-react-codemod@latest preset-19 ./src
自动修复类型问题。 - 更新 JSX 转换配置(
tsconfig.json
或 Babel)。 - 测试 Server Components 和 Server Actions(需框架支持)。
- 使用 React 19 升级指南(https://react.dev/reference/react/upgrade-to-19)。
9. 资源与进一步学习
- 官方文档:https://react.dev
- React 19 升级指南:https://react.dev/reference/react/upgrade-to-19
- React Conf 2024:https://conf.react.dev
- freeCodeCamp 教程:https://www.freecodecamp.org/news/new-react-19-features[](https://www.freecodecamp.org/news/new-react-19-features-you-should-know-with-code-examples/)
- Next.js 15 迁移指南:https://nextjs.org/docs/app-router