😺

React+TypeScriptなWebアプリで、R3Fのtutorial3.(useEffectとuseLayoutEffect)

2023/12/22に公開

Abstract

今回の参考はここ

useEffectとuseLayoutEffectの話。
違いは下記。

  • useEffectは、処理実行中でもレンダリングが実行されるのでちらつく時がある。
  • useLayoutEffectは、処理実行が終わってから、描画実行が実行されるので、ちらつかない。
    useEffectとuseLayoutEffectのチュートリアルを動かしてみたけど、あまり違いは分からんかった。
    ま、成果物を置いとくってことで。

結論

今回の成果物はココ↓
https://github.com/aaaa1597/react-r3f-tutorial003

前提

手順

1.プロジェクト生成 -> VSCodeで開く

めんどいから、前回のプロジェクトから始める。React+TypeScriptなWebアプリで、react-three-fiberのtutorialその1
で、下記コマンドでフォルダ名とか整備する。

フォルダリネームとか
$ NewProject=react-r3f-tutorial002
$ cd ~
$ git clone https://github.com/aaaa1597/react-r3f-tutorial001.git
$ rm -rf react-r3f-tutorial001/.git
$ rm -rf ${NewProject}
$ mv react-r3f-1ststep ${NewProject}

App.tsx

まず全体。

App.tsx
-import React from 'react';
+import React, { useRef, useEffect, useLayoutEffect  } from 'react'
 import './App.css';
-import { Canvas } from '@react-three/fiber'
+import { Canvas, MeshProps} from '@react-three/fiber'

-type Props = {
-  position?: number[];
-  name?: string;
-}

+const BoxEffect = (props: MeshProps) => {
+  const ref = useRef<MeshProps>()
+
+  useEffect(() => {
+    if(ref.current == undefined)  return
+    if(ref.current.position == undefined)
+      ref.current.position = [1,1,1]
+
+    if (ref.current.name === 'A') {
+      ref.current.position.y = 1
+    }
+  })
+  
+  return (
+    <mesh {...props} ref={ref}>
+      <boxGeometry />
+      <meshBasicMaterial color={0x00ff00} wireframe />
+    </mesh>
+  )
+}

-const Box = (props: Props) => {
+const BoxLayoutEffect = (props: MeshProps) => {
+  const ref = useRef<MeshProps>()
+
+  useLayoutEffect(() => {
+    if(ref.current == undefined)  return
+    if(ref.current.position == undefined)
+      ref.current.position = [1,1,1]
+
+    if (ref.current.name === 'B') {
+      ref.current.position.y = -1
+    }
+  })

   return (
-    <mesh {...props}>
+    <mesh {...props} ref={ref}>
       <boxGeometry />
       <meshBasicMaterial color={0x00ff00} wireframe />
     </mesh>
  )
}

-function App() {
+const App = () => {
  return (
    <div style={{ width: "75vw", height: "75vh" }}>
+     <Canvas camera={{ position: [3, 1, 2] }}>
        <ambientLight />
        <directionalLight />
-       <Box position={[-0.75, 0, 0]} name="A" />
-       <Box position={[0.75, 0, 0]} name="B" />
+       <BoxEffect position={[-0.75, 0, 0]} name="A" />
+       <BoxLayoutEffect position={[0.75, 0, 0]} name="B" />
      </Canvas>
    </div>
  );
}

export default App;


出来た!!

地味に↓のコードでMeshPropsを設定するのが分からんくって、エラーでハマった。orz

const ref = useRef<MeshProps>()

それぞれの立方体を、useEffectと、useLayoutEffectで実装したけど、正直変化が分からん。
とはいえ、実装のサンプルに。だれかの役に立つやろ。


React+TypeScriptなWebアプリで、R3Fのtutorial2.(Propsの使い方)


React+TypeScriptなWebアプリで、R3Fのtutorial4.(マウスイベントの使い方)

Discussion