1. ホーム
  2. javascript

[解決済み] ファンクションコンポーネントの関数はどこに行くべきですか?

2022-05-15 19:55:34

質問

私はこのクールな <canvas> アニメーションに変換しようとしています。 ここで を React の再利用可能なコンポーネントに変換しています。このコンポーネントには、canvas 用の親コンポーネントが 1 つと、多数の子コンポーネントである function Ball() .

おそらくパフォーマンス上の理由で Balls をステートレス コンポーネントにする方がパフォーマンス上良いかもしれません。私はステートレス・コンポーネントの作成にあまり慣れていないので、どこで this.update()this.draw で定義された関数は function Ball() .

ステートレス・コンポーネントのための関数は、コンポーネントの内部と外部のどちらに入るのでしょうか?言い換えると、どちらが良いのでしょうか?

1:

const Ball = (props) => {
    const update = () => {
        ...
    }

    const draw = () => {
        ...
    }

    return (
       ...
    );
}

2:

function update() {
     ...
}

function draw() {
     ...
}

const Ball = (props) => {
    return (
       ...
    );
}

それぞれの長所と短所は何ですか?また、私のような特定のユースケースにはどちらが良いのでしょうか?

どのように解決するのですか?

最初に注意すべきことは、ステートレスな関数型コンポーネントはメソッドを持てないということです。 update または draw レンダリングされた Ball がレンダリングされた場合、それがステートレスな機能コンポーネントであれば

ほとんどの場合、関数をコンポーネント関数の外側で宣言した方が、一度だけ宣言し、常に同じ参照を再利用することができます。内部で関数を宣言すると、コンポーネントがレンダリングされるたびに、関数が再び定義されます。

例えば、コンポーネントのプロパティに基づいて異なる動作をするイベントハンドラとして割り当てるために、コンポーネント内部で関数を定義する必要がある場合があります。しかし、それでも、関数を外側で定義することができます Ball の外側で関数を定義し、それをプロパティでバインドすることで、コードをよりすっきりさせることができます。 update または draw 関数の再利用が可能です。

// You can use update somewhere else
const update (propX, a, b) => { ... };

const Ball = props => (
  <Something onClick={update.bind(null, props.x)} />
);

もし、あなたが フック を使っている場合は useCallback を使うことで、関数が再定義されるのはその依存関係 ( props.x が変更されたときのみ再定義されるようにします。

const Ball = props => {
  const onClick = useCallback((a, b) => {
    // do something with a, b and props.x
  }, [props.x]);

  return (
    <Something onClick={onClick} />
  );
}


これは 間違った方法 :

const Ball = props => {
  function update(a, b) {
    // props.x is visible here
  }

  return (
    <Something onClick={update} />
  );
}

を使う場合 useCallback を定義すると update 関数を useCallback フック自体をコンポーネントの外に置くかどうかは、何よりも設計上の判断になりますが、もしあなたが update を再利用する場合や、コンポーネントのクロージャのスコープにアクセスして、例えばステートの読み取り/書き込みを行う必要がある場合などを考慮する必要があります。個人的には、最初から過剰なエンジニアリングを避けるために、デフォルトでコンポーネント内部で定義し、必要な場合にのみ再利用できるようにすることを選択します。さらに、アプリケーション・ロジックの再利用は、より具体的なフックで行うのがよく、コンポーネントはプレゼンテーションのために残しておくのがよいでしょう。フックを使用しながらコンポーネントの外で関数を定義することは、アプリケーションロジックに必要なReactからのデカップリングのグレードに依存します。