React Three Fiber
React 渲染器,用声明式 JSX 语法构建 Three.js 3D 场景,享受 React 组件化和生态系统的完整能力
React Three Fiber 将 Three.js 的 3D 渲染能力与 React 声明式编程结合,通过 JSX 语法直接构建 3D 场景,性能无额外开销。
React Three Fiber
React Three Fiber(R3F)是一个 React 渲染器,让你可以用声明式 JSX 语法构建 Three.js 3D 场景,享受 React 组件化、状态管理和生态系统的完整能力。
技术简介说明
React Three Fiber 是由 Poimandres(pmndrs)开源集体创建的 React 渲染器,它将 Three.js 的 3D 渲染能力与 React 的声明式编程范式深度整合。与传统命令式操作 Three.js 不同,R3F 将 JSX 标记直接转换为 Three.js 对象——例如 <mesh /> 会被动态转换为 new THREE.Mesh()。这意味着 Three.js 中所有功能都能在 R3F 中无例外地使用,且新的 Three.js 特性可以立即被采用。
R3F 的核心价值在于它消除了 3D 场景管理与 React 应用之间的鸿沟。组件在 React 渲染循环之外进行渲染,因此不会产生额外的性能开销。它通过自定义的 reconciler(协调器)与 React 集成,但场景的实际渲染直接运行在浏览器原生帧循环中。这使得 R3F 在大规模场景下的性能甚至优于直接使用 Three.js,因为 React 只在组件 props 发生变化时才参与运算。
作为 React 生态系统的一部分,R3F 天然支持 Suspense、React DevTools、状态管理库(如 Zustand)、以及所有 React 生命周期特性。这让开发者可以用熟悉的 React 模式——组件拆分、hooks、上下文——来构建复杂的 3D 体验,大幅降低了 Web 3D 开发的心智负担。
基本信息
- 官网:https://docs.pmnd.rs/react-three-fiber
- GitHub:https://github.com/pmndrs/react-three-fiber
- License:MIT
- 最新版本:v9.6.1(2026 年 4 月 28 日发布)
- 主要维护者/公司:Poimandres(pmndrs)开源集体,创始人 Paul Henschel(@drcmda)
- GitHub Stars:~31,300
- npm 周下载量:~3,800,000(2026 年 4 月数据)
- 语言:TypeScript(98.7%)
- 兼容版本:React 18 / React 19 / React Native
快速上手
安装
# 核心包
npm install three @react-three/fiber
# 推荐使用 pnpm
pnpm add three @react-three/fiber
# 常用生态库(推荐一起安装)
pnpm add @react-three/drei # 辅助工具集
pnpm add @react-three/rapier # 物理引擎注意:
three是 peer dependency,需要单独安装。
基础配置
R3F 使用 <Canvas> 组件作为 3D 场景的根容器,它会自动创建 WebGL 渲染器、场景和相机:
import { Canvas } from '@react-three/fiber'
function App() {
return (
<Canvas
camera={{ position: [0, 0, 5], fov: 75 }}
// frameloop="demand" // 按需渲染模式(性能优化)
>
{/* 3D 场景内容 */}
</Canvas>
)
}最小示例
import { Canvas, useFrame } from '@react-three/fiber'
import { useRef, useState } from 'react'
import * as THREE from 'three'
// 可交互的旋转立方体组件
function Box(props: JSX.IntrinsicElements['mesh']) {
const meshRef = useRef<THREE.Mesh>(null!)
const [hovered, setHovered] = useState(false)
const [clicked, setClicked] = useState(false)
// 订阅渲染循环,每帧旋转
useFrame((state, delta) => {
meshRef.current.rotation.x += delta * 0.5
meshRef.current.rotation.y += delta * 0.3
})
return (
<mesh
ref={meshRef}
scale={clicked ? 1.5 : 1}
onClick={() => setClicked(!clicked)}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
{...props}
>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
</mesh>
)
}
export default function App() {
return (
<Canvas camera={{ position: [3, 3, 3], fov: 75 }}>
<ambientLight intensity={0.5} />
<directionalLight position={[10, 10, 5]} intensity={1} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
)
}核心概念与架构
Canvas 组件
<Canvas> 是 R3F 场景的入口,它:
- 自动创建 Three.js 的
WebGLRenderer、Scene和Camera - 自动处理 resize 事件和像素比适配
- 提供
frameloop属性控制渲染模式(always/demand/never) - 支持
gl属性传入自定义渲染器配置(v9 起支持异步函数以启用 WebGPU)
Reconciler(协调器)模式
R3F 的核心架构是一个自定义的 React reconciler:
- JSX 标签直接映射到 Three.js 对象:
<mesh />→new THREE.Mesh() - Props 映射到对象属性:
<mesh position={[1, 2, 3]} />→mesh.position.set(1, 2, 3) - 场景渲染在 React 渲染循环之外执行,没有额外开销
- React 仅在组件 props 变化时参与更新,帧更新通过
useFrame直接在原生循环中执行
useFrame Hook
useFrame 是订阅渲染循环的核心 hook:
// 基本用法
useFrame((state, delta) => {
// state: 全局状态(camera, scene, gl, clock, etc.)
// delta: 帧间隔时间(秒)
})
// 带渲染优先级(多 pass 渲染)
useFrame(callback, priority)关键特性:
- 组件卸载时自动取消订阅
- 不触发 React 重渲染,性能极佳
- 多个
useFrame可按 priority 排序执行
核心 Hooks
| Hook | 用途 |
|---|---|
useFrame(callback) | 订阅渲染循环 |
useThree(selector?) | 访问全局状态(camera, gl, scene, size, etc.) |
useLoader(Loader, url) | 加载外部资源(纹理、模型等),支持 Suspense |
useGraph(object) | 解析 Three.js 对象图 |
useRef() | 获取 Three.js 对象的直接引用 |
事件系统
R3F 内置了指针事件系统,所有 3D 对象都可以响应交互:
<mesh
onClick={(e) => console.log('click', e.point)}
onPointerOver={(e) => e.stopPropagation()}
onPointerOut={() => {}}
onDoubleClick={() => {}}
>事件对象包含:point(3D 交点)、distance、face、object、unprojectedPoint 等。
extend 机制
通过 extend 可以将 Three.js 扩展注册到 R3F 的 JSX 命名空间:
import { extend } from '@react-three/fiber'
import { TeapotGeometry } from 'three-stdlib'
extend({ TeapotGeometry })
// 之后可以在 JSX 中使用
<teapotGeometry args={[1]} />核心特性
1. 零开销声明式渲染
R3F 的 reconciler 独立于 React 的 DOM 渲染,场景渲染在浏览器原生帧循环中执行。React 只在组件 props 变化时介入,连续动画通过 useFrame 直接操作 Three.js 对象引用,不触发 React 重渲染。
2. 完整的 Three.js 兼容性
Three.js 中的所有功能都可以在 R3F 中无例外使用。新的 Three.js 版本发布后,R3F 可以立即采用新特性,因为 R3F 本质上只是 Three.js 的 React 接口层。
3. React Suspense 集成
资源加载完全融入 React Suspense 机制:
import { Suspense } from 'react'
import { useGLTF } from '@react-three/drei'
function Model() {
const { scene } = useGLTF('/model.glb')
return <primitive object={scene} />
}
function App() {
return (
<Canvas>
<Suspense fallback={null}>
<Model />
</Suspense>
</Canvas>
)
}4. 内置指针事件系统
所有 3D 对象支持 onClick、onPointerOver、onPointerOut、onDoubleClick 等标准指针事件,无需手动实现射线检测。
5. React 生态系统集成
完全兼容 React DevTools、React 并发模式(startTransition)、React 18+ 的 Suspense、以及所有 React 状态管理库(推荐 Zustand,与 R3F 同一团队维护)。
6. 按需渲染模式
通过 frameloop="demand" 实现仅在状态变化时渲染,而非持续 60fps 循环,大幅降低 GPU 功耗:
<Canvas frameloop="demand">配合 invalidate() 可以在外部状态变更时手动触发渲染帧。
7. TypeScript 全面支持
完整的类型定义,包括 Three.js 对象的类型推导、JSX 元素类型检查,v9 进一步改进了 TypeScript 体验。
8. React Native 支持
通过 @react-three/fiber/native 导入,R3F 可在 React Native / Expo 项目中使用,支持 iOS 和 Android 的 3D 渲染。
9. 性能自适应
通过 useThree 可以访问 performance 对象和 regress() 函数,实现动态性能调节:
function AdaptiveQuality() {
const { performance, regress } = useThree()
// performance.factor 自动在 0-1 之间调整
// regress() 在重交互时临时降低性能因子
}10. 多视口与渲染层
支持多个 <Canvas> 共享同一渲染上下文,以及通过 priority 参数控制渲染 pass 顺序,实现复杂的多层渲染效果。
生态图
React Three Fiber 拥有由 pmndrs 集体维护的丰富生态系统:
核心生态库
| 包名 | 功能 | 说明 |
|---|---|---|
| @react-three/drei | 辅助工具集 | 80+ 个即用组件:OrbitControls、Environment、Html、Text、Float、Stage、ScrollControls、MeshReflectorMaterial 等 |
| @react-three/rapier | 3D 物理引擎 | 基于 Rapier WASM 物理引擎,v2 已支持 R3F v9 + React 19 |
| @react-three/postprocessing | 后处理效果 | 基于 postprocessing 库的 React 封装,支持 Bloom、DOF、SSAO 等效果 |
| @react-three/cannon | 物理引擎 | 基于 Cannon.js 的物理引擎集成(已被 Rapier 逐步替代) |
| @react-three/xr | VR/AR 支持 | WebXR 完整支持,v6 重写后与 UIKit 深度集成,Meta Horizon 采用 |
| @react-three/gltfjsx | 模型转换工具 | 将 GLTF/GLB 3D 模型转换为可复用的 JSX 组件,支持 Draco 压缩 |
| @pmndrs/uikit | 3D UI 组件 | WebGL 渲染的 UI 组件库,v1.0 支持原生 Three.js,Meta 采用 |
| @react-three/flex | Flexbox 布局 | 在 3D 场景中使用 Flexbox 布局 |
| @react-three/a11y | 无障碍支持 | 为 3D 场景添加 ARIA 属性和键盘导航 |
关键依赖
| 依赖 | 说明 |
|---|---|
| three | 核心 3D 引擎(peer dependency) |
| react / react-dom | React 核心库 |
| @react-three/reconciler | 自定义 React reconciler |
| zustand | 推荐状态管理(同团队维护,R3F 内部已包含) |
| react-spring | 弹簧物理动画(常配合使用) |
Drei 常用组件速览
import {
// 相机控制
OrbitControls, PerspectiveCamera,
// 环境 & 光照
Environment, ContactShadows, SoftShadows,
// 文字 & HTML
Text, Html, Center,
// 加载器
useGLTF, useTexture, useVideoTexture,
// 效果
Float, MeshReflectorMaterial, MeshTransmissionMaterial,
// 滚动 & 动画
ScrollControls, useScroll, useSprings,
// 性能
PerformanceMonitor, Detailed, // LOD
// 调试
Stats, Grid, Axes,
} from '@react-three/drei'适用场景
1. React 应用中的 3D 体验
在已有 React 项目中集成 3D 可视化、产品展示、数据可视化等。R3F 与 React 状态管理、路由、组件系统无缝集成。
2. 3D 产品配置器
电商产品展示、汽车配置器、家具定制等场景。配合 useGLTF 加载模型、OrbitControls 交互、状态管理切换配置。
3. 交互式数据可视化
将复杂数据用 3D 图表、粒子系统、力导向图等方式呈现。R3F 的组件化模式让数据驱动的 3D 可视化更易维护。
4. 创意营销网站
品牌展示、产品发布页、沉浸式滚动体验。配合 ScrollControls、后处理效果、物理动画打造视觉冲击力。
5. Web 游戏原型
利用 Rapier 物理引擎、XR 支持、R3F 的组件系统快速构建 Web 游戏原型。适合 game jam 和概念验证。
6. VR/AR 体验
通过 @react-three/xr 构建 WebXR 体验,支持 VR 头显和 AR 手机浏览器,与 UIKit 集成实现空间 UI。
7. 数字孪生与建筑可视化
建筑模型展示、工厂数字孪生、城市规划可视化。按需渲染模式适合长时间运行的监控场景。
开发与工程化
TypeScript 配置
// tsconfig.json 推荐配置
{
"compilerOptions": {
"jsx": "react-jsx",
"strict": true
}
}v9 类型变更:
- Canvas props 类型重命名为
CanvasProps - 移除了
MeshProps等静态导出,使用ThreeElements['mesh']替代 extend函数接受单个 Three.js 类,减少 TypeScript 样板代码
状态管理
推荐 Zustand(与 R3F 同团队,零 bundle 额外开销):
import { create } from 'zustand'
const useStore = create((set) => ({
color: 'orange',
setColor: (color) => set({ color }),
}))
function Box() {
const color = useStore((state) => state.color)
return (
<mesh>
<boxGeometry />
<meshStandardMaterial color={color} />
</mesh>
)
}避免使用 React Context 管理 3D 场景中的高频变化状态——这会导致大范围重渲染。
与 Next.js 集成
// app/page.tsx
'use client' // R3F 需要客户端渲染
import { Canvas } from '@react-three/fiber'
export default function Page() {
return (
<Canvas>
{/* 3D 内容 */}
</Canvas>
)
}注意事项:
- R3F 依赖浏览器 API(WebGL),必须在客户端组件中使用
- 使用
'use client'指令(Next.js App Router)或dynamic importwithssr: false - Next.js 15 + React 19 建议使用 R3F v9
测试
import { render } from '@testing-library/react'
import { Canvas } from '@react-three/fiber'
// R3F v9 使用 React 的 act 函数进行测试
test('renders 3D scene', () => {
render(
<Canvas>
<mesh />
</Canvas>
)
})构建与部署
- R3F 作为标准 npm 包,构建流程与普通 React 应用一致
- 支持 tree-shaking,Three.js 的 ES module 可按需引入
- 注意 Three.js 基础包约 658KB(parsed),R3F reconciler 约 50KB
- 生产环境建议启用 Draco 压缩、KTX2 纹理压缩以减小资源体积
性能与安全
性能优化策略
- 避免频繁 React 状态更新驱动动画:连续动画使用
useFrame直接操作 ref,而非 setState - 按需渲染:非持续动画场景使用
frameloop="demand" - 实例化渲染:大量相同几何体使用
InstancedMesh(Drei 提供<Instances>组件) - LOD(细节层次):使用 Drei 的
<Detailed>组件根据相机距离切换模型精度 - 资源缓存:
useLoader自动缓存相同 URL 的资源 - 共享材质和几何体:全局复用减少 GPU 开销
- 嵌套 Suspense:渐进式加载,先用低精度模型占位
- 性能自适应:使用
PerformanceMonitor动态调整渲染质量 - 并发模式:使用 React 18 的
startTransition延迟构建开销大的几何体 - 控制 draw call:保持在 1000 以内,优先使用合批和实例化
内存管理
- 组件卸载时 R3F 自动清理 Three.js 对象
- 但需注意
useLoader缓存的资源不会自动释放 - 大量资源切换场景时,需手动调用
gl.dispose()和纹理dispose() - 使用 KTX2/Basis Universal 压缩纹理可将 GPU 内存减少 4-8 倍
安全注意事项
- GLTF/GLB 模型来源需信任,恶意模型可能包含过大几何体或嵌入纹理
dangerouslySetInnerHTML模式在 Drei 的Html组件中需注意 XSS 风险- WebXR 场景中的用户输入需做边界验证
- 避免在
useFrame中执行阻塞操作(同步大计算),应使用 Web Worker 或分帧处理
技术对比
| 特性 | React Three Fiber | 原生 Three.js | Babylon.js + react-babylonjs | PlayCanvas |
|---|---|---|---|---|
| 编程范式 | 声明式(React JSX) | 命令式 | 命令式 + 可选声明式 | 命令式 |
| React 集成 | 原生深度集成 | 手动封装 | react-babylonjs 封装 | 手动封装 |
| 渲染后端 | WebGL / WebGPU(实验性) | WebGL / WebGPU(实验性) | WebGL / WebGPU(生产就绪) | WebGL |
| 基础包大小 | ~50KB(+ Three.js ~658KB) | ~658KB(tree-shake ~150-200KB) | ~1.8MB(tree-shake ~300KB) | ~300KB |
| npm 周下载量 | ~3.8M | ~3.5M | ~400K | ~50K |
| GitHub Stars | ~31.3K | ~111K | ~24K | ~9K |
| 物理引擎 | @react-three/rapier(外部) | 自行集成 | Havok(内置) | 自行集成 |
| 后处理 | @react-three/postprocessing | 手动集成 | 内置 | 手动集成 |
| WebXR/VR/AR | @react-three/xr | 手动集成 | 内置(最成熟) | 内置 |
| 可视化调试器 | React DevTools + Drei Stats | Spector.js | Babylon Inspector(最强) | PlayCanvas Editor |
| TypeScript | 优秀 | 良好 | 优秀 | 良好 |
| 商业支持 | 社区(Poimandres) | 社区 | Microsoft | PlayCanvas Ltd |
| 学习曲线 | React + Three.js 双重门槛 | Three.js 概念 | Babylon.js 概念 | PlayCanvas 概念 |
| 移动端支持 | React Native 支持 | 手动适配 | Babylon Native | 手动适配 |
选型建议
- 选 R3F:已有 React 项目需要 3D 能力;团队熟悉 React;需要快速迭代和组件化开发
- 选原生 Three.js:非 React 技术栈;需要极致性能和最小 bundle;需要完全控制渲染管线
- 选 Babylon.js:企业级 XR 应用;需要内置物理引擎和最强调试工具;需要 Microsoft 支持
- 选 PlayCanvas:Web 游戏为主;需要内置编辑器和协作工具;追求极致渲染性能
最佳实践
1. 动画使用 ref 而非 state
// ❌ 错误:每帧触发 React 重渲染
function BadBox() {
const [rotation, setRotation] = useState(0)
useFrame(() => setRotation((r) => r + 0.01))
return <mesh rotation-y={rotation} />
}
// ✅ 正确:直接操作 Three.js 对象
function GoodBox() {
const ref = useRef<THREE.Mesh>(null!)
useFrame(() => {
ref.current.rotation.y += 0.01
})
return <mesh ref={ref} />
}2. 使用 Zustand 管理 3D 场景状态
避免 React Context 在 3D 场景中的性能问题,Zustand 支持 selector 级别的精确订阅:
// ✅ 只在 color 变化时重渲染
const color = useStore((state) => state.color)3. 预加载资源避免闪烁
import { useGLTF, useTexture, Preload } from '@react-three/drei'
function Scene() {
// 预加载
useGLTF.preload('/model.glb')
useTexture.preload('/texture.jpg')
return (
<>
<Model />
<Preload all />
</>
)
}4. 合理使用 memo 和 useMemo
// 缓存复杂几何体计算
const geometry = useMemo(() => {
return createComplexGeometry(params)
}, [params])5. 组件拆分与关注点分离
// 将复杂场景拆分为独立组件
function Scene() {
return (
<>
<Lighting />
<Environment />
<Character />
<UI overlay />
</>
)
}6. 使用 Drei 的 PerformanceMonitor
import { PerformanceMonitor } from '@react-three/drei'
<PerformanceMonitor
onChange={(status) => {
// status: 'crippled' | 'savg' | 'avg' | 'good'
setQuality(status)
}}
/>技术局限与边界
WebGPU 支持不完整
截至 2026 年中,R3F 对 WebGPU 渲染器的支持仍处于实验阶段。核心障碍在于 WebGPU 需要 TSL(Three Shading Language)节点材质系统,而 R3F 尚未提供完善的声明式 API 来封装节点材质。Three.js 本身从 r171(2025 年 9 月)起已支持生产级 WebGPU,但 R3F 的 JSX 适配层仍在追赶。
Bundle 体积
R3F 在 Three.js 基础上增加了约 50KB 的 reconciler 开销,加上 Three.js 基础包(~658KB parsed),总体积较大。如果仅为 3D 功能引入 React,成本不低。但对于已有 React 的项目,增量成本可接受。
React 版本耦合
R3F v9 专为 React 19 设计,v8 支持 React 18。React 版本升级(如 19.2.x)可能导致 reconciler 不兼容,需要等待 R3F 侧适配。
严格模式下的副作用
R3F v9 的 Strict Mode 继承自 React 19 的行为变更,可能暴露隐藏的副作用问题。组件在开发模式下会双重执行,需确保清理逻辑正确。
学习曲线
R3F 要求同时掌握 React 和 Three.js 两套知识体系,入门门槛高于单一框架。对于纯 3D 开发者,React 的声明式范式可能需要适应;对于纯 React 开发者,3D 概念(光照、材质、着色器)是额外学习成本。
复杂后处理限制
@react-three/postprocessing 在复杂效果编排方面仍有局限,与 <View> 组件存在已知兼容性问题。高度定制的后处理管线可能需要直接使用 Three.js 的 EffectComposer。
调试复杂度
3D 场景的调试比 2D DOM 更复杂。虽然有 React DevTools 和 Drei 的 Stats,但 GPU 性能问题、着色器错误等仍需借助外部工具(Spector.js、Browser DevTools GPU 面板)。
学习资源
官方文档
- React Three Fiber 官方文档 — API 参考、指南和示例
- Drei 文档 — 辅助组件详细文档
- v9 迁移指南 — 从 v8 升级的完整指南
系统课程
- Wawa Sensei: Learn React Three Fiber — 最受推荐的系统课程,从入门到进阶
- Three.js Journey — Three.js 权威课程,含 R3F 物理和后处理章节
- Bilibili: React Three Fiber 3D 网页开发 — 中文完整视频教程
免费教程
- SBCode React Three Fiber Tutorials — 免费系列教程
- GitHub 教程合集(41 个示例 + 12 个项目) — 从基础到高级
- YouTube: R3F Crash Course for Beginners — 2025 年新手速成课
社区
- Poimandres Discord — 最活跃的 R3F 社区频道
- Three.js Discourse — Three.js 官方论坛,大量 R3F 讨论
- r/threejs — Reddit Three.js 社区
- Poimandres 博客 — 生态更新和技术文章
工具
- GLTF → JSX 在线转换 — 将 GLTF 模型在线转换为 JSX 组件
- Drei Storybook — Drei 组件交互式预览
2026 年现状
版本与生态
- 核心库:
@react-three/fiberv9.6.1(2026 年 4 月),专注 React 19 兼容与稳定性 - Drei:v10.7.7 稳定版 / v11.0.0-alpha.5 开发中
- Rapier:v2 已发布,完全支持 R3F v9 + React 19
- UIKit:v1.0(2025 年 10 月)正式发布,已开放给整个 Three.js 生态
- XR:v6.6.x 持续维护,Meta Horizon 平台采用
社区活跃度
- GitHub Stars:~31,300
- npm 周下载量:~3,800,000(2026 年 4 月,较 2026 年初的 ~700K 大幅增长)
- 总提交数:2,849
- 总发布版本:133 个
- 活跃维护,issue 和 PR 处理持续进行中
发展趋势
- WebGPU 适配是 2026 年最重要的方向,Three.js 已生产就绪,R3F 正在追赶
- UIKit v2.0 规划中,将进一步完善 3D UI 能力
- 空间计算持续升温,XR + UIKit 的组合为 WebXR 提供了完整的 React 解决方案
- 移动端性能优化成为关注焦点,60fps 在移动设备上的实现方案日趋成熟
- AI 辅助开发开始融入,3D 场景生成的 AI 工具与 R3F 的声明式 API 天然契合
- Triplex 可视化编辑器加入 pmndrs 并开源,为 R3F 提供了缺失的可视化编辑能力
知名用户
Vercel、Zillow、ReadyPlayer.me 等公司在产品中使用 React Three Fiber, agencies(创意机构)是 R3F 的最大用户群体之一,尤其在需要 React + 3D 结合的项目中。