You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Three-Fiber路由切换时Canvas不更新残留3D模型问题

解决方案

问题本质

你的Canvas挂载在路由体系外部,里面的<View>和torus组件不会随路由切换自动卸载。即使Home组件卸载后splashView的ref变为null,react-three-fiber也不会自动销毁这些3D元素,导致残留显示。

可行方案:路由驱动的条件渲染

通过监听当前路由,仅在首页路径下渲染3D内容,利用React的声明式渲染自动处理组件卸载与3D资源清理。

步骤1:导入路由状态钩子

在组件顶部导入useLocation:

import { useLocation } from 'react-router-dom';

步骤2:监听当前路由

在组件内部获取当前路由信息:

const location = useLocation();

步骤3:条件渲染3D内容

修改Canvas内的代码,仅当路由为首页时渲染torus相关组件:

<Canvas eventSource={ref} className={styles.canvas}>
  {/* 仅在首页且Home组件已挂载时渲染3D元素 */}
  {(['/', '/home'].includes(location.pathname) && splashView.current) && (
    <View track={splashView}>
      <ambientLight intensity={0.1} />
      <directionalLight color="red" position={[0, 0, 5]} />
      <mesh>
        <torusGeometry/>
        <meshStandardMaterial />
      </mesh>
    </View>
  )}
</Canvas>

完整修改后的代码示例

import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';
import { Canvas, View } from '@react-three/fiber';
import { useRef, forwardRef } from 'react';
import Navbar from './Navbar';
import Syllabus from './Syllabus';

// 已通过forwardRef处理的Home组件
const Home = forwardRef((props, ref) => {
  return <div ref={ref}>首页内容</div>;
});

export default function App() {
  const ref = useRef();
  const splashView = useRef();
  const location = useLocation();

  return (
    <div>
      <BrowserRouter>
        <div ref={ref}>
          <Navbar/>
          <Routes>
            <Route index element={<Home ref={splashView}/>}/>
            <Route path="/home" element={<Home ref={splashView}/>}/>
            <Route path="/syllabus" element={<Syllabus/>}/>
          </Routes>
        </div>
      </BrowserRouter>
      <Canvas eventSource={ref} className={styles.canvas}>
        {(['/', '/home'].includes(location.pathname) && splashView.current) && (
          <View track={splashView}>
            <ambientLight intensity={0.1} />
            <directionalLight color="red" position={[0, 0, 5]} />
            <mesh>
              <torusGeometry/>
              <meshStandardMaterial />
            </mesh>
          </View>
        )}
      </Canvas>
    </div>
  );
}

原理说明

  • 当路由切换出首页时,条件渲染的表达式返回false,<View>及其子组件会被React卸载。
  • react-three-fiber会自动处理卸载时的Three.js资源清理,无需手动操作。
  • 额外判断splashView.current是为了确保Home组件已完成DOM挂载,避免<View>跟踪不存在的元素。

内容的提问来源于stack exchange,提问作者Cookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:57:45