有効なフック:依存配列


ヘイフレンズ!私はクリスチャン👋, ドイツからの意欲的なフロントエンド開発者.私は、将来の参照のために主に反応の有効なフックについてのポストを書いています.私は頻繁にuseeffectを使用しますが、私は時々、高度なユースケースと複雑さと闘争することが起こる.それで、私はuseeffectの私の理解をブラッシュして、反応のコンポーネントライフサイクルとJavaScript閉鎖のより大きい絵にそれを適合させようとします.🚀
私は、the official documentation of useEffectでUseeffectを読み始めました.私は非常にあなたが役に立つ効果についての詳細なガイドのためにそれをチェックアウトすることをお勧めします.

効果についての基本


フックは反応v 16で導入された.7.0アルファと、それらはコードの再使用可能な部分にコンポーネントロジックをカプセル化する方法を提供します.さらにフックは、シームレスにコンポーネントの状態のさまざまな部分と相互作用することができますまたは主要な利点です.

効果の精神モデル


UseEffectフックは、最も頻繁に使用されるフックの反応によって提供されるフックです.すべての機能コンポーネントに対して、コンポーネントdidmountとcomponent didupdateとcomponent entdidunmountの代替としてuseeffectを考えることができます.
UseEffectコンポーネントのライフサイクルにフックし、副作用を実行する方法を提供します.副作用は、コンポーネント関数の外部に影響する操作です.戻り値が関数のスコープ外のデータに依存している場合、副作用は基本的に関数を汚します.
クラスのコンポーネントでは、上記のLifeCycleメソッドに関連していた“マウント”、“更新”と“アンマウント”に関するライフサイクルについて考えるでしょう.しかし、機能的なコンポーネントとフックで、それはちょうど「レンダリング」に関してコンポーネントライフサイクルについて考えるほうがよいです.

効果


useeffectフックのシグネチャはuseEffect(effectFn, dependencyArray)です.最初にeffectFnパラメタについて話しましょう、そして、単にそれを我々の「影響」と呼びます(official useEffect guideのように).

すべてのレンダリングに効果を実行する


知っておくべき重要性:デフォルトですべてのレンダリングで効果を実行します.この振舞いはdependendyArray、すなわちフックの2番目のパラメータを使用することでカスタマイズできます.後で依存関係の配列の詳細!
import { useEffect } from "react";

export default function MyComponent() {
  useEffect(() => {
    // inside our effect
  });
}

閉鎖に関する語


一般的な効果やフックは、自分自身の関数本体以外の変数、つまり、コンポーネントのスコープ内で変数と対話するときにとても興味深いものです.効果がコンポーネントの状態変数を使用する一般的なケースを考えましょう.
import { useEffect, useState } from "react";

export default function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // inside our effect
    console.log("I run on every render whatsoever", count);
  });

  return (
    <div>
      <span>{count}</span>
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>
        +++
      </button>
    </div>
  );
}
コンポーネントが最初にレンダリングされるときに何が起こります(これは「実装」とも呼ばれます)?
  • MyComponentと呼ばれています
  • 状態変数は0
  • の値で初期化されます
  • 効果関数は初期化され、countの状態変数を超えて閉じられる.countのようにconsole.log(count)に解決している
  • DOMは、コンポーネント
  • から返されたJSXに従って塗装される
  • エフェクトが実行され、コンソールに0を記録します.
  • console.log(0)が新たな値に設定されていれば、ステップ1からステップ5を経て再描画しなければならない.すべてのレンダリングでは、新しい効果が初期化され、呼び出されます.
    しかし、私たちの効果は、はるかに高価であると想像し、必ずしも各レンダリングで実行する必要はありません.我々の効果がcountだけに依存するので、我々はcountが変わるときだけ、それが走ることを望みます.
    依存配列を入力してください!

    依存配列


    依存関係の配列を使用すると、効果が実行されるときに細かい粒度のコントロールを取得します.依存配列は、(オプション)2番目の引数としてuseEffectフックに渡されます.
  • 依存関係の配列を渡さない場合は、すべてのレンディングで実行されます.
  • 空の配列を渡すと、効果はすべてのレンダリングで実行されます.
  • 状態変数を持つ配列を渡すと、これらの変数のうちの少なくとも1つが変化した場合にのみ、その効果が実行されます.
  • 最初のレンダリングだけで効果を実行する


    useEffect(() => {
      // inside our effect
      console.log("I run only on first render!");
    }, []); // Empty dependency array
    

    カウントが変更された場合のみ有効です


    import { useEffect, useState } from "react";
    
    export default function MyComponent() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        // inside our effect
        console.log(count);
      }, [count]);
      //  ^^^^^ if count changes between re-renders, run our effect! If not, skip the effect.
    
      return (
        <div>
          <span>{count}</span>
          <button onClick={() => setCount((prevCount) => prevCount + 1)}>
            +++
          </button>
        </div>
      );
    }
    

    クリーンアップ


    場合によっては、コンポーネントがアンマウントされた場合、つまりクリーンアップ機能を実行したい場合があります.一般的に、イベントリスナーをDOMに付けた場合は、コンポーネントがアンマウントされたときに削除します.またはマウント後に一度間隔を設定している場合は、アンマウント後の間隔をクリアする必要があります.
    アンマウント後に関数を実行するには、その関数からそのクリーンアップ関数を返さなければなりません.
    import { useEffect, useState } from "react";
    
    export default function MyComponent() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        const intervalId = setInterval(() => {
          setCount((prevCount) => prevCount + 1);
          //        ^^^^^^^^^ important: pass a callback function to setCount
          // this way the interval will always use the latest count state value
        }, 1000);
    
        return () => {
          // cleanup function
          clearInterval(intervalId);
        };
      }, []);
    
      return (
        <div>
          <span>{count}</span>
          <button onClick={() => setCount((prevCount) => prevCount + 1)}>
            +++
          </button>
        </div>
      );
    }
    

    Stackblitzで私のコードを再生する


    素晴らしい時間をコーディングして!❤️