React hooks
让我们在 React Three Fiber 中看看我们常用的 React hooks 以及如何使用它们,同时避免常见的陷阱。
如果您不熟悉 React hooks,我建议您先阅读官方文档。
useState
useState 允许您创建一个状态变量以及一种更新它的函数。
const [color, setColor] = useState("white");
它返回一个包含两个元素的数组:
- 状态变量
- 更新它的函数。
您可以像这样使用它:
import { useState } from "react"; // ... const Cube = (props) => { const [color, setColor] = useState("white"); useControls({ changeColorToRed: button(() => setColor("red")), changeColorToBlue: button(() => setColor("blue")), changeColorToGreen: button(() => setColor("green")), }); return ( <mesh {...props}> <boxGeometry /> <meshStandardMaterial color={color} /> </mesh> ); }; // ...
每次点击按钮时,立方体的颜色都会改变。
由于更新状态会触发重新渲染,所以应避免在循环或条件中调用 useState
。
我们将在 React Three Fiber hooks 课程中了解如何以正确的方式进行频繁更新,并在优化课程中讨论常见的陷阱。
目前,以下是使用 useState
的一些经验法则:
- 避免将
useState
用于快速变化的值。 - 在尽可能深的层次使用它。通过这种方式,您将避免重新渲染不需要重新渲染的项目。
useMemo
useMemo 允许你缓存一个值。这意味着仅当其依赖项发生变化时,才会重新计算该值。
让我们用一个缓存的 material 替换掉我们当前的 material:
import { useMemo, useState } from "react"; // ... const Cube = (props) => { // ... const material = useMemo(() => <meshStandardMaterial color={color} />, []); return ( <mesh {...props}> <boxGeometry /> {material} </mesh> ); }; // ...
- 第一个参数是一个返回需要缓存值的函数。在我们的例子中,它是一个 material 组件。
- 第二个参数是一个依赖项数组。我们传递了一个空数组,这意味着 material 只会被计算一次。
- 返回的值是缓存的值。
现在,当我们点击按钮时,立方体的颜色不会改变,因为 material 没有重新计算。
为了解决这个问题,我们需要将color
作为依赖项传递:
const material = useMemo(() => <meshStandardMaterial color={color} />, [color]);
现在,当我们点击按钮时,立方体的颜色会改变,因为 material 会在color
状态改变时重新计算。
我们这样做是为了展示useMemo
的工作原理,但在这种情况下,并不需要缓存 material。React Three Fiber 已经为我们做了必要的优化。
useMemo
可以带来益处的场景有:
- 当一个值的计算成本很高,并且在一个频繁渲染的组件中使用时。
- 当一个组件有很多子组件,你想避免重新渲染它们时。
- 当一个组件有很多属性,你想避免重新渲染它时。
刚开始使用 React 和 r3f 时,不要为了过早优化而使用
useMemo
。这可能会很棘手并导致 Bug。在遇到性能问题时再考虑使用。
useRef
useRef 允许您创建一个在渲染之间持久化的可变值。
它通常用于存储对 DOM 元素 或 Three.js 对象 的引用,但您也可以用它来存储任何值。
useRef
的好处是当它的值改变时不会触发重新渲染。对 r3f 来说,这对于动画或任何频繁变化的值非常完美。
React Three Fiber: The Ultimate Guide to 3D Web Development
✨ You have reached the end of the preview ✨
Go to the next level with Three.js and React Three Fiber!
Get full access to this lesson and the complete course when you enroll:
- 🔓 Full lesson videos with no limits
- 💻 Access to the final source code
- 🎓 Course progress tracking & completion
- 💬 Invite to our private Discord community
One-time payment. Lifetime updates included.