这个教程会帮助你学会如何在常见的场景搭配TypeScript使用 React Three Fiber
本教程假定您具有一些 React 和 TypeScript 的知识,并且将基于此初始codesandbox,因此只需fork它并跟随即可!
React 的 useRef 不会自动推断类型,即使将其指向一个类型化的 ref。您可以通过在 useRef 的泛型中传递类型来手动为 ref 添加类型:
import { useRef, useEffect } from 'react'
import { Mesh } from 'three'
function Box(props) {
const meshRef = useRef<Mesh>(null!)
useEffect(() => {
console.log(Boolean(meshRef.current))
}, [])
return (
<mesh {...props} ref={meshRef}>
<boxGeometry />
<meshBasicMaterial />
</mesh>
)
}
感叹号是一个非空断言运算符,它会告诉TS,当我们在effect中访问它时,ref.current是有定义的。
react-three-fiber 接受缩写的 props,如标量、字符串和数组,因此您可以声明性地设置属性而不会产生副作用。
以下是不同变体的 props:
import { Euler, Vector3, Color } from 'three'
rotation: Euler || [x, y, z]
position: Vector3 || [x, y, z] || scalar
color: Color || 'hotpink' || 0xffffff
每个属性都有扩展类型,您可以从中提取这些属性的类型。
import { Euler, Vector3, Color } from '@react-three/fiber'
rotation: Euler
position: Vector3
color: Color
如果您正在组件外部输入属性(例如 store或hook),则这特别有用。
react-three-fiber也可以接受第三方元素并将其通过 extend 方法进行扩展。
import { useRef, useEffect } from 'react'
import { GridHelper } from 'three'
import { extend } from '@react-three/fiber'
class CustomElement extends GridHelper {}
extend({ CustomElement })
扩展过后就可以直接在项目代码中用 JSX 的方式进行使用这些元素了。
但是这样的声明式的写法要注意一个问题, TypeScript 不会知道它们或它们的 props。
react-three-fiber导出了一些heplers 类型,您可以使用它们来定义不同类型的节点。这些节点将会对我们添加到全局JSX名称空间的元素进行类型标注。
Node
Object3DNode
BufferGeometryNode
MaterialNode
LightNode
因为我们得自定义 Element 是一个对象,我们可以使用Object3DNode类型去定义它。
import { useRef, useEffect } from 'react'
import { GridHelper } from 'three'
import { extend, Object3DNode } from '@react-three/fiber'
class CustomElement extends GridHelper {}
extend({ CustomElement })
declare module '@react-three/fiber' {
interface ThreeElements {
customElement: Object3DNode<CustomElement, typeof CustomElement>
}
}
<customComponent />
react-three-fiber 是可扩展的而且也导出自己的内部类型,比如 render props、canvas props 还有 events 等等。
Intersection
Subscription
RenderCallback
RootState
Performance
Dpr
Size
Viewport
Camera
Props
Events
EventManager
ThreeEvent