aurora blog
  • JS

    • 基本汇总
    • Date时间
    • Array方法
    • String 方法
    • Object方法
    • RegExp正则
    • Es6 新特性等
    • Event-Loop
    • Http and Https
    • for in和for of区别
    • Web Worker
    • Promise && async
    • 堆内存 & 栈内存
    • JS设计模式探索
    • npm & yarn
    • Fetch和Axios的区别
    • 学习及面试问题整理
    • URL 输入到页面加载过程
    • 跨域&nginx本地项目代理
  • FE框架

    • react

      • 基本用法
      • react生命周期
      • hooks 16.8版本后
      • Route原理
      • Redux源码解析
      • React16 Fiber
      • React-VirtualDOM
      • React事件委托机制
      • React性能优化
      • 状态管理方案对比
      • React 18新特性
    • vue

      • vue 基本用法
      • vue 生命周期
      • VirtualDOM
      • vue 事件委托
      • vue 架构
      • vue 状态管理
      • 问题等
    • React-Native

      • React-Native 基本用法
    • 微前端

      • 遇到的问题
    • 鸿蒙 harmony

      • harmony 基础
  • 构建工具

    • webpack

      • Webpack配置详解
      • Webpack的使用
      • Babel-polyfill
      • webpack面试题
    • vite

      • vite配置详解
      • vite面试题
    • rollup

      • Rollup配置详解
      • rollup面试题
    • 构建工具对比
  • 性能优化

    • 性能优化策略
    • 缓存策略
    • 性能优化面试题
  • 浏览器

    • 浏览器渲染原理
    • 浏览器缓存机制
    • 浏览器面试题
  • 工程化

    • 代码规范
    • 工程化面试题
  • 前端安全

    • XSS 攻击与防护
    • CSRF 攻击与防护
    • 前端安全面试题
  • 移动端开发

    • 移动端适配
    • 移动端开发面试题
  • 前端监控

    • 错误监控
    • 性能监控
    • 前端监控面试题
  • Typescript

    • Typescript详解
  • Servers

    • Nodejs
    • Nginx
  • Git命令

    • git常用规范
  • 数据库

    • mongodb
    • mongodb
  • Other

    • Jenkins自动化部署

React 18 新特性

  • React 18 概述
  • 核心特性
    • 1. 并发渲染(Concurrent Rendering)
    • 2. 自动批处理(Automatic Batching)
    • 3. Suspense 增强
    • 4. Transitions(useTransition)
    • 5. Deferred Values(useDeferredValue)
    • 6. useId
    • 7. useSyncExternalStore
    • 8. useInsertionEffect
    • 9. Strict Mode 更新
  • 新的 API
    • createRoot
    • hydrateRoot
  • 迁移指南
    • 1. 更新 React 版本
    • 2. 更新入口文件
    • 3. 处理类型定义
    • 4. 更新测试库
  • 兼容性
    • 浏览器支持
    • 库兼容性
  • 性能提升
    • 1. 更快的渲染
    • 2. 更好的用户体验
    • 3. 服务端渲染改进
  • 最佳实践
    • 1. 使用新的 API
    • 2. 利用并发特性
    • 3. 注意副作用
  • 总结

React 18 概述

React 18 是 React 的最新版本,引入了并发特性(Concurrent Features),提升了用户体验和开发体验。

核心特性

1. 并发渲染(Concurrent Rendering)

概念:

  • React 可以中断、暂停和恢复渲染工作
  • 根据优先级调度更新
  • 提升应用响应性

优势:

  • 更好的用户体验
  • 避免阻塞主线程
  • 更流畅的交互

使用:

import { createRoot } from 'react-dom/client';

// React 18 新的 API
const root = createRoot(document.getElementById('root'));
root.render(<App />);

// React 17 及之前(已废弃)
// ReactDOM.render(<App />, document.getElementById('root'));

2. 自动批处理(Automatic Batching)

概念:

  • React 18 自动批处理所有状态更新
  • 减少重新渲染次数
  • 提升性能

React 17 行为:

function handleClick() {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React 17 会触发两次重新渲染
}

React 18 行为:

function handleClick() {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React 18 自动批处理,只触发一次重新渲染
}

// 异步操作也会批处理
function handleClick() {
  fetch('/api').then(() => {
    setCount(c => c + 1);
    setFlag(f => !f);
    // React 18 也会批处理
  });
}

强制同步更新:

import { flushSync } from 'react-dom';

function handleClick() {
  flushSync(() => {
    setCount(c => c + 1);
  });
  // 这里 count 已经更新
  flushSync(() => {
    setFlag(f => !f);
  });
  // 这里 flag 已经更新
}

3. Suspense 增强

服务端渲染支持:

import { Suspense } from 'react';
import { createRoot } from 'react-dom/client';

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <ProfilePage />
    </Suspense>
  );
}

并发 Suspense:

function App() {
  return (
    <>
      <Suspense fallback={<div>Loading profile...</div>}>
        <ProfilePage />
      </Suspense>
      <Suspense fallback={<div>Loading posts...</div>}>
        <PostsPage />
      </Suspense>
    </>
  );
}

Suspense 列表:

import { SuspenseList } from 'react';

function App() {
  return (
    <SuspenseList revealOrder="forwards" tail="collapsed">
      <Suspense fallback={<div>Loading...</div>}>
        <ProfilePicture id={1} />
      </Suspense>
      <Suspense fallback={<div>Loading...</div>}>
        <ProfilePicture id={2} />
      </Suspense>
      <Suspense fallback={<div>Loading...</div>}>
        <ProfilePicture id={3} />
      </Suspense>
    </SuspenseList>
  );
}

4. Transitions(useTransition)

概念:

  • 标记非紧急更新
  • 允许 React 中断这些更新
  • 优先处理用户交互

使用:

import { useTransition } from 'react';

function SearchResults() {
  const [isPending, startTransition] = useTransition();
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  
  function handleChange(e) {
    const value = e.target.value;
    setQuery(value); // 紧急更新
    
    startTransition(() => {
      // 非紧急更新
      setResults(search(value));
    });
  }
  
  return (
    <div>
      {isPending && <div>Searching...</div>}
      <input value={query} onChange={handleChange} />
      <ResultsList results={results} />
    </div>
  );
}

优势:

  • 保持 UI 响应性
  • 避免阻塞用户交互
  • 更好的用户体验

5. Deferred Values(useDeferredValue)

概念:

  • 延迟更新值
  • 允许 React 先处理紧急更新
  • 类似防抖但更智能

使用:

import { useDeferredValue } from 'react';

function SearchResults({ query }) {
  const deferredQuery = useDeferredValue(query);
  const results = useMemo(() => {
    return search(deferredQuery);
  }, [deferredQuery]);
  
  return <ResultsList results={results} />;
}

与 useTransition 的区别:

  • useTransition:标记更新为过渡
  • useDeferredValue:延迟值更新

6. useId

概念:

  • 生成唯一 ID
  • 服务端和客户端一致
  • 解决 hydration 不匹配问题

使用:

import { useId } from 'react';

function Checkbox() {
  const id = useId();
  
  return (
    <>
      <label htmlFor={id}>Checkbox</label>
      <input id={id} type="checkbox" />
    </>
  );
}

// 多个 ID
function Form() {
  const nameId = useId();
  const emailId = useId();
  
  return (
    <>
      <label htmlFor={nameId}>Name</label>
      <input id={nameId} type="text" />
      
      <label htmlFor={emailId}>Email</label>
      <input id={emailId} type="email" />
    </>
  );
}

注意:

  • 不要用于列表的 key
  • 不要用于生成 CSS 选择器
  • 只用于需要唯一 ID 的场景

7. useSyncExternalStore

概念:

  • 订阅外部数据源
  • 避免 tearing(撕裂)问题
  • 适合状态管理库

使用:

import { useSyncExternalStore } from 'react';

function useStore(selector) {
  const store = useStoreInstance();
  
  return useSyncExternalStore(
    store.subscribe,
    () => selector(store.getState()),
    () => selector(store.getServerState()) // SSR
  );
}

适用场景:

  • Redux、Zustand 等状态管理库
  • 订阅外部数据源
  • 避免并发渲染问题

8. useInsertionEffect

概念:

  • 在 DOM 更新前执行
  • 主要用于 CSS-in-JS 库
  • 避免样式闪烁

使用:

import { useInsertionEffect } from 'react';

function useCSS(rule) {
  useInsertionEffect(() => {
    const style = document.createElement('style');
    style.textContent = rule;
    document.head.appendChild(style);
    
    return () => {
      document.head.removeChild(style);
    };
  });
  
  return rule;
}

执行时机:

  • 在 DOM 更新前
  • 在所有 useLayoutEffect 之前
  • 适合注入样式

9. Strict Mode 更新

双重渲染:

  • 开发模式下组件会渲染两次
  • 帮助发现副作用问题
  • 生产环境不受影响

行为:

function Component() {
  console.log('render'); // 开发模式会打印两次
  
  useEffect(() => {
    console.log('effect'); // 会执行两次
    return () => {
      console.log('cleanup'); // 也会执行
    };
  }, []);
  
  return <div>Component</div>;
}

目的:

  • 检测副作用
  • 确保组件可重用
  • 提升代码质量

新的 API

createRoot

替换 ReactDOM.render:

// React 18
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(<App />);

// 卸载
root.unmount();

// React 17(已废弃)
// ReactDOM.render(<App />, document.getElementById('root'));

hydrateRoot

服务端渲染:

import { hydrateRoot } from 'react-dom/client';

const root = hydrateRoot(document.getElementById('root'), <App />);

迁移指南

1. 更新 React 版本

npm install react@18 react-dom@18

2. 更新入口文件

// 旧代码
import ReactDOM from 'react-dom';
ReactDOM.render(<App />, document.getElementById('root'));

// 新代码
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);

3. 处理类型定义

npm install @types/react@18 @types/react-dom@18

4. 更新测试库

npm install @testing-library/react@latest

兼容性

浏览器支持

  • Chrome、Firefox、Safari、Edge(最新版本)
  • 不支持 IE11

库兼容性

已兼容:

  • React Router v6
  • Redux Toolkit
  • React Query
  • 大部分主流库

需要更新:

  • 部分旧的状态管理库
  • 部分测试库

性能提升

1. 更快的渲染

  • 并发渲染提升响应性
  • 自动批处理减少渲染次数
  • 更好的调度算法

2. 更好的用户体验

  • 保持 UI 响应性
  • 避免阻塞交互
  • 更流畅的动画

3. 服务端渲染改进

  • Suspense 支持 SSR
  • 流式渲染
  • 选择性 hydration

最佳实践

1. 使用新的 API

  • 使用 createRoot 替代 ReactDOM.render
  • 使用 useId 生成唯一 ID
  • 使用 useTransition 标记非紧急更新

2. 利用并发特性

  • 使用 startTransition 包装非紧急更新
  • 使用 useDeferredValue 延迟值更新
  • 使用 Suspense 处理异步加载

3. 注意副作用

  • 注意 Strict Mode 的双重渲染
  • 确保副作用可重用
  • 正确清理资源

总结

React 18 的主要改进:

  1. 并发渲染:提升应用响应性
  2. 自动批处理:减少重新渲染
  3. Suspense 增强:更好的异步处理
  4. Transitions:优先处理用户交互
  5. 新 Hooks:useId、useTransition、useDeferredValue 等
  6. 更好的 SSR:流式渲染和选择性 hydration

建议:

  • 尽快升级到 React 18
  • 利用并发特性提升用户体验
  • 注意兼容性问题
  • 遵循最佳实践
最近更新:: 2025/11/20 14:50
Contributors: liyulai
Prev
状态管理方案对比