React18核心并发渲染
通过createRoot、useTransition、自动批处理等特性提升应用性能和用户体验,向下兼容,升级成本低
1. 并发渲染(Concurrent Rendering) ---- 底层核心
- 它允许React的渲染过程被中断、暂停、恢复或放弃,不再是过去“一旦开始就必须执行到底"的同步渲染模式
- 核心价值:解决长任务阻塞主线程导致的界面卡顿(如大数据渲染、复杂计算时,输入/点击等交互仍能响应)
- 注意:这是底层能力,无需开发者直接调用,通过后续的useTransition、createRoot等API间接启用
2. 新的根节点API: createRoot(启用新特性的入口)
- 18废弃了旧的ReactDOM.render,推出createRoot作为新的根节点创建方式,这是启用所有18新特性的前提
// 17及之前
import ReactDOM from 'react-dom'
ReactDOM.render(<APP />, document.getElementById('root'))
// 18推荐
import ReactDOM from 'react-dom/client'
const root = ReactDOM.createRoot(document.getElementById('root))
root.render(<APP />) // 首次渲染
root.unmount() // 新增:优雅卸载组件(替代旧的unmountComponentAtNode)
3. 自动批处理(Automatic Batching) --- 性能优化
- 批处理值React合并多个状态更新,只触发一次重渲染,减少不必要的DOM操作
- 18把批处理能力扩展到所有场景(包括异步回调、定时器、Promise等)
// 17 异步回调中会触发2次重渲染
function handleClick(){
fetch('/api/data').then(() => {
setCount(c => c + 1)
setFlag(f => !f)
})
}
// 18 自动批处理,仅触发1次重渲染
// 无需手动修改代码,框架层面自动完成
// 如需禁用批处理:使用ReactDOM.flushSync(() => { setCount(1) })
4. useTransition --- 区分紧急/非紧急更新
- 用于标记非紧急更新(如列表筛选、大数据渲染),避免阻塞紧急更新(如输入框打字、按钮点击)提升交互流畅度
import { useTransition, useState } from 'react'
function SearchBox() {
const [input, setInput] = useState('')
const [list, setList] = useState([])
const [isPending, startTransition] = usetransition() // 加载态 + 标记非紧急更新
const handleChange = (e) => {
// 紧急更新:输入框内容(优先执行,不卡顿)
setInput(e.target.value)
// 非紧急更新:列表筛选(可被中断)
startTransition(() => {
const filtered = largeDataList.filter(item => item.includes(e.target.value))
setList(filtered)
})
}
return (
<div>
<input value={input} onChange={handleChange} />
{/* 非紧急更新时显示加载态 */}
{isPending ? <div>筛选中...</div> : list.map(item => <div key={item}>{item}</div>)}
</div>
)
}
5. useDeferredValue --- 延迟更新非紧急状态
- 效果类似useTransition,但针对单个状态值,适合需要延迟同步的场景(如输入框联想词)
import { useDeferredValue, useSate } form 'react'
function InputWithSuggestion() {
// 延迟更新:suggestionValue会滞后与input,且更新不阻塞主线程
const suggestionValue = useDeferredValue(input, {timeoutMs: 200})
// 基于延迟值渲染联想词(不会阻塞输入)
const suggestions = getSuggestions(suggestionValue)
return(
<div>
<input value={input} onChange={(e) => setInput(e.target.value)} />
<div> {suggestions.map(s => <div key={s}> {s} </div>)} </div>
</div>
)
}
6. Suspense增强---支持数据加载(实验性)
- 18正式扩展Suspense的能力,从代码分割延伸到数据加载(需配合React Query、SWR等库或Next.js框架),实现等待数据时显示加载态
import { Suspense } from 'react'
import DataComponent from './DataComponent'
function App() {
return (
<div>
<h1>主内容</h1>
{/* 数据加载完成前显示fallback */}
<Suspense fallback={<div>加载数据中...</div>}>
<DataComponent/>
</Suspense>
</div>
)
}
7. 服务端渲染(SSR)优化
- 18对SSR做了大幅升级
- 流式SSR:逐步输出HTML内容,无需等待所有数据加载完成,提升首屏渲染速度
- Suspense配合SSR:支持服务端渲染时的加载态显示,避免首屏空白
8.严格模式增强
- 18的严格模式会模拟组件挂载-卸载-重新挂载的过程,检测非幂等的副作用(如未清理的定时器、重复的请求),帮助开发者写出更健壮的代码
React19核心是简化开发体验
通过Actions、use()钩子,乐观更新等特性减少样板代码,完善服务器组件,聚焦“更简洁、更原生”的开发模式
1. Actions(核心):统一状态更新与表单处理
- 彻底重构了表单提交、异步操作的处理方式,替代了传统的
useState + useEffect + 事件处理组合,内置了加载态、错误处理、异步兼容能力 - 自动收集表单数据,无需手动维护onchange
- 原生支持异步操作,自动管理加载/错误状态
- 可结合Suspense实现加载态展示
import { useActionState } from 'react';
// 定义 Action 函数(支持异步)
async function submitForm(prevState, formData) {
// 自动获取表单数据,无需手动绑定
const username = formData.get('username');
const password = formData.get('password');
// 模拟异步请求
try {
const res = await fetch('/api/login', {
method: 'POST',
body: JSON.stringify({ username, password }),
});
if (!res.ok) throw new Error('登录失败');
return { success: true, error: null };
} catch (err) {
return { success: false, error: err.message };
}
}
function LoginForm() {
// useActionState 管理 Action 状态:初始值、Action函数、加载态
const [state, formAction, isPending] = useActionState(
submitForm,
{ success: false, error: null } // 初始状态
);
return (
<form action={formAction}>
<input name="username" placeholder="用户名" />
<input name="password" type="password" placeholder="密码" />
{/* 加载态 */}
<button type="submit" disabled={isPending}>
{isPending ? '登录中...' : '登录'}
</button>
{/* 错误提示 */}
{state.error && <div style={{ color: 'red' }}>{state.error}</div>}
{/* 成功提示 */}
{state.success && <div style={{ color: 'green' }}>登录成功!</div>}
</form>
);
}
2. use()钩子:简化异步数据获取
- 替代了
useEffect + useState处理异步数据的模式,允许直接在组件体重消费Promise,配合Suspense实现简洁的一部加载逻辑,无需手动管理加载/完成状态
import { use, Suspense } from 'react';
// 异步获取数据的函数
function fetchUser(userId) {
return fetch(`/api/users/${userId}`).then(res => res.json());
}
// 消费异步数据的组件
function UserProfile({ userId }) {
// 直接用 use() 消费 Promise,无需 useEffect
const user = use(fetchUser(userId));
return (
<div>
<h3>{user.name}</h3>
<p>邮箱:{user.email}</p>
</div>
);
}
// 父组件(用 Suspense 处理加载态)
function App() {
return (
<div>
<h1>用户信息</h1>
<Suspense fallback={<div>加载用户数据中...</div>}>
<UserProfile userId="123" />
</Suspense>
</div>
);
}
3. useOptimistic:原生支持乐观更新
-
乐观更新指:先更新UI反馈用户,再等待后端相应
-
19内置了useOptimistic钩子,无需手动写临时状态,大幅简化点赞、表单提交等场景的体验优化
import { useOptimistic, useActionState } from 'react' // 异步提交点赞的Action函数 async function toggleLike(prevState, postId) { await fetch(
/api/posts/${postId}/like, {method: 'POST'}) return { liked: !prevState.liked } } function LikeButton({postId}) { // 基础状态管理 const [state, toggleLikeAction] = useActionState(toggleLike, {like: false}) // 乐观更新:先更新UI, 再等请求完成 const [optimisticState, addOptimistic] = useOptimistic( state, (currentState) => ({ ...currentState, liked: !currentState.liked }) ) const handleClick = () => { // 1.立即更新UI 乐观更新 addOptimistic() // 2.发送异步请求 togleLikeAction(postId) } return ( <button onclick={handleClick} style={{color: optimisticState.liked ? 'red' : 'black'}}> { optimisticState.liked ? '取消点赞' : '点赞'} ) }
4. 服务器组件(RSC)正式稳定
-
19完善了服务器组件(Server Components)的规范和实现,明确区分
-
服务器组件:运行在服务端,无交互、无副作用,可直接访问数据库,减少客户端包体积
-
客户端组件:允许在浏览器,支持交互(如点击、输入),需显式标记'use client'
-
核心价值
- 减少客户端JS体积,提升首屏加载速度
- 服务端直接获取数据,避免客户端跨域请求
- 前后端逻辑复用更简单
-
在Next.js中使用示例
// 服务器组件(无需 'use client',默认运行在服务端) async function PostList() { // 直接在组件中获取数据(服务端执行,无跨域) const posts = await fetch('/api/posts').then(res => res.json()); return ( <div> {posts.map(post => ( <PostItem key={post.id} post={post} /> ))} </div> ); } // 客户端组件(需显式标记,支持交互) 'use client'; function PostItem({ post }) { const [liked, setLiked] = useState(false); return ( <div> <h3>{post.title}</h3> <button onClick={() => setLiked(!liked)}> {liked ? '已点赞' : '点赞'} </button> </div> ); }
5. 实用改进
- ref转发简化:无需forwardRef,直接通过ref属性传递给子组件,减少样板代码
- 错误边界增强:支持捕获更多类型的错误(如异步错误),且使用更简单
- 表单原生增强:支持formAction、formMethod等原生表单属性,无需手动绑定
- TypeScrit优化:类型定义更精准,减少不必要的类型断言,提升类型推导体验
- 严格模式改进:更友好的副作用检测,帮助开发者写出更健壮的代码