在使用 React Three Fiber 的 Gatsby 应用程序中使用 Context 实例化网格时出错

问题描述 投票:0回答:1

在我的 gatsby 应用程序中,我尝试利用实例多次显示网格。为此,我使用以下代码 https://gltf.pmnd.rs/:

import React, { useRef, useMemo, useContext, createContext } from "react"
import { useGLTF, Merged } from "@react-three/drei"
import plank from "./planks.gltf"

const context = createContext()
export function Instances({ children, ...props }) {
  const { nodes } = useGLTF(plank)
  const instances = useMemo(
    () => ({
      PlankStyle: nodes.PlankStyle02029,
    }),
    [nodes]
  )
  return (
    <Merged meshes={instances} {...props}>
      {instances => <context.Provider value={instances} children={children} />}
    </Merged>
  )
}

export function Planks(props) {
  const instances = useContext(context)
  console.log(instances)
  return (
    <group {...props} dispose={null}>
      <instances.PlankStyle
        position={[-3.088, -0.01, 5.742]}
        rotation={[0, Math.PI / 2, 0]}
        scale={[1, 0.947, 1]}
      />
      <instances.PlankStyle
        position={[-3.088, -0.01, 6.752]}
        rotation={[0, Math.PI / 2, 0]}
        scale={[1, 0.947, 1]}
      />
      <instances.PlankStyle
        position={[-3.088, -0.01, 7.518]}
        rotation={[0, Math.PI / 2, 0]}
        scale={[1, 0.947, 1]}
      />
    </group>
  )
}

useGLTF.preload(plank)

然后我将此组件加载到我的索引页上,如下所示:

...
const IndexPage = () => {
  return (
      <Canvas shadows dpr={[1, 1.5]} camera={{ position: [-1.5, 1, 5.5], fov: 45, near: 1, far: 20}}>
        <Suspense fallback={null}>
          <Planks />
        </Suspense>
      </Canvas>
  )
}

export default IndexPage

这会引发错误,当我记录

instances
时,它是未定义的,所以我认为它一定是与上下文相关的东西。鉴于这是盖茨比,我觉得有一些额外的箍我必须跳过才能让它工作,只是不知道那是什么。

我研究了在 gatsby 中使用上下文,并发现了有关如何将整个应用程序包装在上下文提供程序中的各种指南。我试了一下:

export const AppContext = createContext()

export const AppProvider = ({ children, ...props }) => {
  const { nodes } = useGLTF(plank)

  const instances = useMemo(
    () => ({
      PlankStyle: nodes.PlankStyle02029,
    }),
    [nodes]
  )

  return (
    <AppContext.Provider
      value={{
        instances,
      }}
    >
      <Merged meshes={instances} {...props}>
        {instances => (
          <AppContext.Provider value={instances} children={children} />
        )}
      </Merged>
    </AppContext.Provider>
  )
}

instances
确实被定义了。然而,当我尝试将其加载到我的画布中时,我收到了此错误
R3F: Hooks can only be used within the Canvas component!
尝试将该部分包装在画布中,但随后它就因错误而变得疯狂,而且无论如何我都需要能够将其与其他元素一起放入现有的画布中.

鉴于这些模型是特定于页面的,我想弄清楚如何让它与上面发布的第一个代码片段更加一致。

在这一点上,我愿意接受任何建议,因为我想不出其他任何东西(除了手动将位置复制到我想避免的重复网格)

reactjs three.js gatsby react-three-fiber
1个回答
0
投票

我已经设法让它在没有上下文的情况下工作。至少现在我几乎可以从https://gltf.pmnd.rs/复制所有实例,而无需手动添加位置n东西。我想现在已经足够好了,但仍然感谢任何建议。

import React, { useRef, useMemo, useContext, createContext } from "react"
import { useGLTF, Merged } from "@react-three/drei"
import plank from "./planks.gltf"

export function Planks() {
  const { nodes } = useGLTF(plank)
  const instances = useMemo(
    () => ({
      PlankStyle: nodes.PlankStyle02029,
    }),
    [nodes]
  )
  return (
    <Merged meshes={instances}>
      {({ PlankStyle }) => (
        <>
          <group dispose={null}>
            <PlankStyle
              position={[-3.088, -0.01, 5.742]}
              rotation={[0, Math.PI / 2, 0]}
              scale={[1, 0.947, 1]}
            />
            <PlankStyle
              position={[-3.088, -0.01, 6.752]}
              rotation={[0, Math.PI / 2, 0]}
              scale={[1, 0.947, 1]}
            />
            <PlankStyle
              position={[-3.088, -0.01, 7.518]}
              rotation={[0, Math.PI / 2, 0]}
              scale={[1, 0.947, 1]}
            />
          </group>
        </>
      )}
    </Merged>
  )
}

useGLTF.preload(plank)
© www.soinside.com 2019 - 2024. All rights reserved.