React hooks

Starter pack

React Three Fiberで使用する一般的なReact hooksと、それらの使用方法、よくある落とし穴を回避する方法を見てみましょう。

もしReact hooksに慣れていない場合は、まず公式ドキュメントを読むことをお勧めします。

useState

useStateを使うことで、状態変数とその更新関数を作成できます。

const [color, setColor] = useState("white");

これは2つの要素を持つ配列を返します:

  • 状態変数
  • それを更新する関数

次のように使用します:

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を使用するように置き換えてみましょう:

import { useMemo, useState } from "react";

// ...

const Cube = (props) => {
  // ...
  const material = useMemo(() => <meshStandardMaterial color={color} />, []);

  return (
    <mesh {...props}>
      <boxGeometry />
      {material}
    </mesh>
  );
};

// ...
  • 第一引数はメモ化する値を返す関数です。今回の場合、それはmaterialのコンポーネントです。
  • 第二引数は依存関係の配列です。ここでは空の配列を渡しています。これはmaterialが一度だけ計算されることを意味します。
  • 戻り値はメモ化された値です。

これで、ボタンをクリックしても、cubeの色は変わりません。なぜなら、materialが再計算されないからです。

これを修正するために、colorを依存関係として渡す必要があります:

const material = useMemo(() => <meshStandardMaterial color={color} />, [color]);

これで、ボタンをクリックするとcubeの色が変わります。なぜなら、colorの状態が変わると、materialが再計算されるからです。

これを行った理由は、useMemoの動作を示すためですが、この場合、materialをメモ化する必要はありません。React Three Fiberはすでに必要な最適化を行ってくれます。

useMemoが有益であるケースは次の通りです:

  • 頻繁にレンダリングされるコンポーネントで値の計算が高コストになる場合。
  • 多くの子コンポーネントを持つ場合で再レンダリングを避けたい場合。
  • 多くのpropsを持つコンポーネントで再レンダリングを避けたい場合。

Reactr3fを使い始めた時は、早期最適化のためにuseMemoを使用しないでください。使用が難しく、バグにつながる可能性があります。パフォーマンス問題が発生した場合に使用することをお勧めします。

useRef

useRef は、レンダー間で持続する変更可能な値を作成するために使用されます。

通常、DOM要素Three.jsオブジェクトへの参照を格納するために使用されますが、任意の値を格納することも可能です。

useRefの良い点は、その値が変更されても再レンダーを引き起こさないことです。r3fの場合、これはアニメーションや頻繁に変更される値に最適です。

End of lesson preview

To get access to the entire lesson, you need to purchase the course.