R3F报错hooks仅可在Canvas内使用 子组件调用useThree仍触发错误
问题解决方法
根因分析
- 核心错误是跨包导入R3F API:你从旧版本包
react-three-fiber导入Canvas、useFrame,又从新版官方包@react-three/fiber导入useThree,两个包的运行上下文完全隔离,导致useThree无法识别外层的Canvas组件,哪怕MyRotatingBox确实写在Canvas内部也会抛出上下文不存在的报错。 - 次要问题:代码中未从
react导入useState,运行时也会触发报错;props.mouse没有从外层传入,逻辑无法正常生效。
修复代码
统一所有R3F相关导入到@react-three/fiber,补全缺失依赖,调整鼠标交互逻辑即可正常运行:
import React, { useRef, useState } from "react"; import { Canvas, useFrame, useThree } from "@react-three/fiber"; import "./styles.css"; const MyRotatingBox = () => { const { mouse } = useThree(); const myMesh = useRef(); const [onHover, setOnHover] = useState(false); useFrame(() => { if (onHover && myMesh.current) { // 可自行调整旋转系数匹配交互手感 myMesh.current.rotation.x = mouse.y * Math.PI; myMesh.current.rotation.y = mouse.x * Math.PI; } }); return ( <mesh ref={myMesh} onPointerOver={(e) => setOnHover(true)} onPointerOut={(e) => setOnHover(false)} > <boxGeometry args={[1, 1, 1]} /> <meshPhongMaterial color="royalblue" /> </mesh> ); } export default function App() { return ( <div className="App"> <Canvas> <MyRotatingBox /> <ambientLight intensity={0.1} /> <directionalLight position={[5, 5, 5]} /> </Canvas> </div> ); }
额外说明
如果不需要单独提取mouse变量,也可以直接在useFrame的回调参数里拿到全局状态,省略单独调用useThree的步骤:
useFrame((state) => { if (onHover && myMesh.current) { myMesh.current.rotation.x = state.mouse.y * Math.PI; myMesh.current.rotation.y = state.mouse.x * Math.PI; } });
内容的提问来源于stack exchange,提问作者ioanna marinou
相关产品推荐
相关产品推荐

