React Hooks のわかりやすい解説 — useCallback

Dec 03 2022
この記事では、React の useCallback フックを使用するタイミングと方法、およびほとんどのジュニア開発者が犯す間違いについて説明します。
はじめに ローカルの IDE で作業を進めたい場合は、ここで GitHub リポジトリを見つけることができます。参照等価性は、JavaScript とコンピューター サイエンス全体の基本的な概念です。

入門

ローカルの IDE でフォローしたい場合は、ここでGitHub リポジトリを見つけることができます。

  • clone
  • cd client
  • npm i
  • npm start

参照等価性は、JavaScript とコンピューター サイエンス全体の基本的な概念です。それでは、動作中のデモンストレーションから始めましょう。

モバイルで使いやすいように、記事全体にスクリーンショットを埋め込んでいます。デスクトップを使用していてクローンを作成した場合は、referentialEquality.js実行して出力を観察するか、以下に埋め込まれた JSFiddle スニペットで遊んでください。

integer 1がと厳密に等しいかどうかを評価するとinteger 1、コンソールに が出力されますtrue。これは、まあ… が と厳密に等しいinteger 1 ためinteger 1です。

整数は厳密に等しい

2 つの文字列を評価すると、同じ結果が得られます。

文字列は厳密に等しい

明らかに、これは同じ値の2 つのプリミティブ データ型の場合に常に当てはまります。

では、データ構造はどうでしょうか。たとえば、同じキーと値のペアを持つ 2 つのオブジェクト リテラル? 空のオブジェクト リテラルはどうですか?

オブジェクトは厳密には等しくありません

なぜこれは印刷されるのですかfalse?これら 2 つのオブジェクト リテラルが厳密に等しいかどうかを比較する場合、JavaScript はそれぞれのメモリ アドレスを使用します。

つまり、これら 2 つのオブジェクトには同じ値が含まれている可能性がありますが、同じオブジェクトを参照していません。これらは同じように見えますが、メモリ内で 2 つの異なるスペースを占めています。

2 つのオブジェクト リテラル、2 つの配列リテラル、または 2 つの関数を比較する場合でも、同じことが当てはまります。

配列は厳密には等しくありません

これをさらに実証するために、関数を定義しますfunc。これは無名関数を返し、さらに別のもの ( JSX 要素など) を返します。

ふり機能コンポーネントの作成

次に、によって返される値に等しい2 つの異なる関数firstRenderおよびを割り当てます。secondRenderfunc

関数定義の割り当て

funcReact 機能コンポーネントと考えてください。 while は最初のレンダリングではその内部のfirstRender関数であり、2 番目のレンダリングではその内部の関数です。secondRender

firstRenderは同じ値を返し、同じ定義から割り当てられますが、参照等価性はsecondRenderありません。その結果、コンポーネントがレンダリングされるたびに、この関数が再定義されます。

2 つの関数は厳密には等しくありません

残念ながら、JavaScript では、Python のようにこれらのメモリ アドレスを出力するのは簡単ではありませんが、参照と値のもう少し詳しい説明については、 freeCodeCamp のこの記事を参照してください。

このトピックは内容が濃くなる可能性があり、今夜のクラスで教える必要はありません。したがって、今のところ、次のことを覚えておいてください。

  • プリミティブ データ タイプ===プリミティブ データ タイプ
  • データ構造!==データ構造。

スターター コード

アプリを起動したら、BookDetails.jsxコンポーネントを開いて再保存します。React 開発サーバーで最初に気付くのは、WARNING若い開発者が無視しがちな共通点です。従業員を増やして本番用のコードを書き始めると、リンターは に組み込まれているものよりもさらに厳密になりますcreate-react-app。一部のリンターは、これらに対処する前にプッシュすることを許可しませWARNINGSん。ERRORSERRORS

無視するのではなく、対処法を考えてみましょう。

React が提案するソリューション

注:これを作成するには、最初に再保存する必要がある場合がありますBookDetails.jsxWARNING

React Docsを掘り下げると、WARNING次のように、これに対するやや混乱する提案された解決策を解読できます。

1. の中に関数定義を含めますuseEffect

  • 再定義しない限り、この関数を他の場所で呼び出すことはできません。
  • これにより、状態または小道具が変更されるuseEffect たびにトリガーされ、無限の再レンダリングが発生する場合があります。私たちの場合、API 呼び出しの後に状態セッター関数を呼び出しているため、API が無限のエンドポイント リクエストで過負荷になる可能性があります。
  • 関数は呼び出されません。
  • コンポーネントが初めてレンダリングされるときに、関数が定義され、 がトリガーされuseEffect、コンポーネントが再レンダリングされ、関数が再定義され、 がトリガーされ、useEffectコンポーネントが再レンダリングされます。関数を再定義します…

最も簡単で好ましい解決策は、「それを含める」ことです。つまり、getBookDetails関数定義を .xml ファイル内に移動しますuseEffect。これは、カプセル化として知られるオブジェクト指向プログラミングの原則に準拠しています。

しかし、関数を別の場所で呼び出す必要があることがわかっているとしましょう。後で再定義する必要がありますか?それは私たちにとってあまりドライではありません。

依存配列を変更して、関数参照を含めましょう。あなたはuseEffect今このように見えるはずです。

依存配列に関数を含める

そしての上でgetBookDetails定義されたままです。useEffect

関数の元の定義

今、私たちは新しいWARNING

関数を依存関係配列に含めながら useEffect の外で定義すると、無限の再レンダリングが発生します

useCallback フックに入る

つまり、useCallbackフックを使用すると、コンポーネントの再レンダリングの間に関数をキャッシュまたは「メモ化」できます。と同様のタスクを実行しますがuseMemo、そのニュアンスについては別の記事で説明します。

この詳細に興味がある場合は、React docsで詳細を読むことができます。

彼らの警告に注意してください:

useCallbackパフォーマンスの最適化としてのみ依存する必要があります。これがないとコードが機能しない場合は、根本的な問題を見つけて、最初に修正してください。次に、追加してuseCallbackパフォーマンスを向上させることができます。

useCallback構文

useCallbackの構文は、useEffectすでに知っている の構文と非常によく似ています。それぞれの骨格をご覧ください。

2 つのフックが同一の構文スケルトンを持っている

わずかな違いは、無名関数に関数を実行するようuseEffectに指示するのに対し、 では、戻りを参照に割り当てて、他の場所で呼び出されるようにすることです。useCallback

useCallback の使用

useCallbackまず、からインポートします'react'。新しい行を追加するのではなく、他のインポートと一緒に構造を解除することをお勧めします。

同じパッケージから分解されたアイテムは、同じ行で最適に​​インポートされます

getBookDetailsこれで、関数呼び出しから返された値に割り当てることができますuseCallback

useCallback の戻り値をリファレンスに割り当てます

次に、 のすべての構文を追加しますuseCallback。依存関係の配列を覚えておいてください!

useCallback のスケルトンを埋める

asyncこの例では、パラメータの前に必要です。

非同期を追加

最後に、関数のロジックをコード ブロックに追加します。

useCallback のコード ブロックにロジックを追加する

保存すると、… 別のWARNING.

useCallback の戻り値は id の値に依存します

依存関係配列がid変数を追跡する必要があるのはなぜですか?

これを考えてみましょう。

  • の値がid変更された場合、getBookDetails別のエンドポイントにヒットする必要があるため、React はそれを再定義する必要があります。getBookDetails文字どおりの定義はの値に依存しますid
両方のフックの完成版

そして最後に、それだけです!React dev サーバーに緑色が表示されます。幸せなリンターは幸せなシニア開発者です。そして、幸せなシニア開発者はあなたも幸せです!

私はいつも新しい友達や同僚を探しています。この記事が役に立ち、接続したい場合は、ウェブ上の私の家で私を見つけることができます.

GitHub | ツイッター| リンクトイン| Webサイト

資力

  • 参照の等価性
  • JavaScript プリミティブ データ型とデータ構造
  • カプセル化
  • useCallback
  • React ドキュメント