組み込みのReactフック

フック を用いると、コンポーネントから様々な React の機能を使えるようになります。組み込まれたフックを使うこともできますし、組み合わせて自分だけのものを作ることもできます。このページでは、React に組み込まれた全てのフックを説明します。


state フック

state は、ユーザの入力などの情報をコンポーネントに記憶させることができます。例えば、フォームコンポーネントは入力された文字を保存し、画像ギャラリーのコンポーネントは選択された画像を保持できます。

コンポーネントに state を追加するには、次のフックのいずれかを使います:

  • useState は直接アップデート可能な state 変数を定義します
  • useReducer は、reducer function 内でアップデートロジックを用いた state 変数を定義します。
function ImageGallery() {
const [index, setIndex] = useState(0);
// ...

context フック

Context を用いると、コンポーネントは props を渡すことなく、離れた親要素から情報を取得できるようになります。例えば、アプリの最上位のコンポーネントは、現在の UI テーマをコンポーネントの階層に関係なく全てのコンポーネントに渡すことができます。

  • useContext を用いて値を使用できるようにします。
function Button() {
const theme = useContext(ThemeContext);
// ...

ref フック

ref を用いると、コンポーネントはレンダリングに用いない情報を保持することができます。例えば DOM node やタイムアウト ID などが当てはまるでしょう。state と違い、ref の値の更新はコンポーネントを再レンダーしません。ref は、React パラダイムからの「脱出ハッチ」です。これらは組み込みのブラウザ API のような React ではないシステムを操作するときに役立ちます。

  • useRef は ref を宣言します。useRef にはどんな値でも格納できますが、多くの場合、DOM ノードを格納するために使われます。
  • useImperativeHandle を用いると、コンポーネントが公開する ref をカスタマイズできます。これは殆ど用いられることはありません。
function Form() {
const inputRef = useRef(null);
// ...

エフェクト フック

エフェクトは、コンポーネントを外部システムに接続し、同期させることができます。これには、ネットワーク、ブラウザの DOM、アニメーション、別の UI ライブラリを使って書かれたウィジェット、その他の React 以外のコードの処理が含まれています。

  • useEffect は外部のシステムとコンポーネントを接続します。
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
// ...

エフェクトは、React パラダイムからの「脱出ハッチ」のようなものです。エフェクトをアプリケーションのデータフローを調整するために使ってはいけません。外部のシステムとやりとりを行わないならば、エフェクトは必要ないかもしれません。

useEfefct には、タイミングの違いによってまれに使われることのある 2 つのバリエーションがあります:

  • useLayoutEffect はブラウザが画面を再描画する前に発火します。このフックでレイアウトを測定できます。
  • useInsertionEffect は React が DOM に変更を加える前に発火します。ライブラリはダイナミック CSS をこのフックで挿入できます。

performance フック

再レンダーのパフォーマンスを最適化する通常の方法は、不要な処理を減らすことです。例えばキャッシュを再利用したり、データの変更がない場合の再レンダーをスキップしたりするよう、React に伝えることができます。

不要な処理やレンダリングを減らすためには、これらのフックを用いることができます:

  • useMemo を用いると高負荷な計算の結果をキャッシュできます。
  • useCallback を用いると最適化されたコンポーネントに渡す前の段階で、関数定義をキャッシュできます。
function TodoList({ todos, tab, theme }) {
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...
}

画面を更新するために再レンダーをスキップできない場合もあるでしょう。その場合、同期が必要なブロック更新(ユーザの文字入力など)を、ユーザ インターフェイスをブロックする必要のない非ブロック更新(図の更新など)から分離することで、パフォーマンスを向上することができます。

レンダリングを優先するには、これらのフックを用いることができます:

  • useTransition を用いると、状態の遷移を非ブロックとしてマークし、他のアップデートによる割り込みを許可します。
  • useDeferredValue を用いると、UI の重要でない部分の更新を延期して他の部分を先に更新させることができます。

その他のフック

これらのフックはライブラリの開発者には便利かもしれません。しかし、アプリケーションのコードでは通常は用いられることはありません。

  • useDebugValue を用いると、React DevTools が表示するカスタムフックのラベルをカスタマイズできます。
  • useId を用いると、コンポーネントがユニークな ID をコンポーネントそのものに関連付けることができます。通常はアクセシビリティ API とともに使用されます。
  • useSyncExternalStore を用いると、コンポーネントは外部のストアを参照できるようになります。

独自のフック

独自のカスタムフックを JavaScript の関数として定義することもできます。