フロントエンド開発の仕事をしているときに、useMemo に出会ったことがあるかもしれません。これに慣れていない人のために、React で useMemo を使用する方法と、最も重要/顕著な使用例について説明します。
useMemo は、Web アプリのパフォーマンスに役立つ優れた組み込みフックです。我々は、 reactでは、コンポーネントの状態や props に変更があるたびにコンポーネントがレンダリングされることを知っています。
再レンダリングされるコンポーネントは、内部で使用されている関数も再計算します。
したがって、重くて高価な関数がある場合、毎回計算する必要があるため、パフォーマンスに影響を与える可能性があります。 useMemo は、パフォーマンスを最適化するためにこれらの関数をメモ化するのに役立ちます。
useMemo を理解するには、メモ化とは何かを振り返る必要があります。
大量のデータをフェッチするなど、負荷の高い関数がある場合、メモ化は、関数を何度も呼び出す必要がないように、その関数の結果を保存する方法です。
useMemo はラップしている関数を取得し、その関数の結果をキャッシュして、計算をやり直すことなく必要なときに提供できるようにします。
組み込みフックとして、React からフックをインポートし、トップレベルで使用できます。
次に、定数または変数を宣言し、それをフックの結果に割り当てることで、負荷の高い計算を useMemo でラップすることができます。
useMemo が関数を再計算する必要があるかどうかを決定する方法として、依存関係を追加することを忘れないでください。
依存関係が変更された場合、useMemo は常に正しい結果をキャッシュするように値を再計算することを認識します。
import { useMemo } from 'react' ; function someExpensiveFunction ( n ) { return n * n; } function myFunction ( {n} ) { const result = useMemo( () => someExpensiveFunction(n), [n]); return ( < div > {result} </ div >
); }
たとえば、値 5 を渡した場合、
n
の場合、値 25 がキャッシュされます。 n
値を 7 に変更すると、useMemo はそれが依存関係であることを認識し、値 49 に再計算し、代わりにその結果をキャッシュします。これは、フロントエンド アプリケーションが API にリクエストを行う場合に特に便利です。
これらのリクエストは、特に大量のデータをフェッチする場合、コストが高くなる可能性があります。
おそらく、アプリケーションにはこのデータを必要とするコンポーネントがいくつかありますが、コンポーネントがレンダリングされるたびに API 呼び出しを行う必要はありません。
その場合、useMemo を使用して結果をキャッシュするのが最善の策かもしれません。
import React, { useMemo } from 'react' ; import axios from 'axios' ; const ApiComponent = () => { const memoizedResults = useMemo( async () => { try { const apiResponse = await axios.get( 'http://apicall.com/somedata' ); return apiResponse.data; } catch (error) { return error; } }, []); return ( < div > {apiResponse} </ div >
) }
ご覧のとおり、依存関係は空です。これは、値が実際には変更されないため、一度だけレンダリングしたいからです。最初にレンダリングするときに API 呼び出しを 1 回だけ行う必要があります。
その後、この値は後続のレンダリングで再利用されます。
フックは便利ですが、useMemo を常に使用することが必ずしも良いアイデアであるとは限りません。計算を「保存」するために、作成したすべての関数を useMemo でラップしたくなるかもしれません。
ただし、必要がないときにこれを使用すると、実際にはアプリケーションの速度が低下する可能性があります。
1. 簡単な計算
useMemo でラップしている関数が単純な計算である場合、useMemo を使用するコストがより重大になる可能性があります。
関数の重みが非常に小さい (O(n) 時間など) と判断できる場合は、フックは必要ないと判断するのが適切です。
2. 関数が外部の状態や変数に影響を与える可能性がある場合
関数が他のグローバル変数の変更を伴う場合、または他のグローバル変数に依存する場合、useMemo を使用することは得策ではない可能性があります。
前に説明したように、useMemo は依存関係が変更された場合にのみ関数を再計算します。
ただし、関数が必ずしも依存関係の変更ではない変数または呼び出しを使用する場合、値は再計算されず、キャッシュされた結果が不正確になります。
useCallback に精通している人もいるかもしれません。useMemo と同様の目的を果たします。この記事では useCallback については深く掘り下げませんが、2 つの関数をいつ使用するかを区別します。
useMemo と useCallback はどちらも何かをメモ化することでアプリケーションを最適化するために機能するフックであるため、混同しやすい場合があります。ただし、メモしている内容が違うので注意が必要です。
ほとんどの場合、useMemo は値をメモ化し、useCallback は関数をメモ化します。名前からわかるように、 useCallback はコールバック関数、特に props として子コンポーネントに渡されるコールバック関数をメモ化するために使用されます。コールバック関数は、時間の経過とともに変化する可能性のある特定の値または参照に依存する場合があります。つまり、これらの関数を更新すると、それらを使用するコンポーネントで再レンダリングが発生します。したがって、それらをメモ化すると、最適化にコストがかかる可能性がある再レンダリングを防ぐことができます。
ただし、useMemo は関数と値の両方をメモ化できるため、useCallback フックの代わりに使用できます。それでも、状況のコンテキストを考慮し、フックを適切に使用して意図どおりに使用することが重要です。
useMemo は全体的に…値をメモ化し、再レンダリングを回避できる、優れた柔軟なフックです。フックを戦略的に使用することで、アプリケーションを最適化して計算を削減し、ユーザーがより高速でスムーズなエクスペリエンスを得ることができるようになります。
useMemo でユーザーに思い出に残る体験を提供しましょう!