React Hooks

React HooksはReact 16.8で導入された重要な機能であり、関数コンポーネントがクラスコンポーネントの一部の特性(状態管理やライフサイクルメソッドの使用など)を利用できるようにします。

Hooksを使用することで、Reactコンポーネントをより簡潔かつ柔軟に記述できます。

1. React Hooksとは?

React Hooksは関数コンポーネントの拡張メカニズムであり、クラスコンポーネントを記述することなくReactの機能を使用できます。主なHooksにはuseState, useEffect, useContext, useReducer, useCallback, useMemo, useRef、およびuseImperativeHandleなど。これらのHooksはReactの機能にアクセスする手段を提供し、コードをより良く整理して再利用できるようにします。

2. 主なReact Hooks

useState

useStateHookを使用すると、関数コンポーネントでローカル状態を使用できます。これは状態値と、その状態値を更新する関数を返します。

例

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

useEffect

useEffectHookを使用すると、関数コンポーネントで副作用操作(データ取得、サブスクリプション管理、DOM操作など)を実行できます。これは毎回のレンダリング後に実行されます。

例

import React, { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds(seconds => seconds + 1);
    }, 1000);

    return () => clearInterval(interval);
  }, []); // 空配列を2番目の引数として指定すると、コンポーネントのマウント時とアンマウント時のみ実行されます

  return <p>Timer: {seconds} seconds</p>;
}

以下は、主なReact Hooksとその用途です:

useState - 関数コンポーネントにstateを追加するために使用します。時間の経過とともに変化するデータを追跡するために使用できます。

const [state, setState] = useState(initialState);

useEffect- 副作用操作(データ取得、サブスクリプション、DOMの手動変更など)を実行するために使用します。クラスコンポーネントのcomponentDidMount、componentDidUpdate、componentWillUnmountライフサイクルに似ています。

useEffect(() => {
  // 执行副作用操作
  return () => {
    // 清理操作
  };
}, [dependencies]); // 依赖数组

useContext- React contextを使用して、コンポーネントツリーで受け渡されるデータにアクセスするために使用します。各コンポーネントを経由してpropsを渡す必要はありません。

const value = useContext(MyContext);

useReducer- より複雑なstateロジックに使用します。reducer関数と初期状態を受け取り、現在のstateとactionをdispatchするための関数を返します。

const [state, dispatch] = useReducer(reducer, initialState);

useCallback- メモ化されたコールバック関数を返すために使用し、不要なレンダリングを防ぎます。

const memoizedCallback = useCallback(
  () => {
    // 回调函数体
  },
  [dependencies] // 依赖数组
);

useMemo- 計算結果をメモ化して、毎回のレンダリング時に再計算することを避けるために使用します。

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useRef- DOM要素や値への参照を作成するために使用します。レンダリング間で状態を保持できます。

const refContainer = useRef(initialValue);

useImperativeHandle- refを使用する際にDOM要素のメソッドを公開するために使用します。

useImperativeHandle(ref, () => ({
  // 暴露的方法
}));
useLayoutEffect - 与 useEffect 类似,但它在所有的 DOM 变更之后同步执行。这在需要读取 DOM 布局并同步触发重渲染时非常有用。

useLayoutEffect(() => {
  // 副作用操作
}, [dependencies]);

useDebugValue- React開発者ツールにカスタムHookのラベルを表示するために使用します。

useDebugValue(value);

3. React Hooksを使用する利点

  • より簡潔なコンポーネントロジック:クラスコンポーネントを記述する必要がなく、関数コンポーネントとHooksを使用して状態とライフサイクルを管理できます。
  • コードの再利用性の向上:Hooksは、ロジックを再利用可能な関数に抽出し、重複コードを減らすのに役立ちます。
  • より良いパフォーマンスの最適化:使用useEffect, useCallback, useMemoなどのHooksは、副作用とパフォーマンスの消費をより正確に制御できます。

4. 注意事項

  • Hooksはトップレベルでのみ使用する:ループ、条件分岐、またはネストされた関数内でHookを呼び出さないでください。Hooksが毎回のレンダリングで常に同じ順序で呼び出されるようにしてください。
  • ESLintプラグインの使用:React公式がeslint-plugin-react-hooksプラグインを提供しており、Hookの正しい使用法を確認するのに役立ちます。

5. 例

以下は、複数のReact Hooksを使用した例です:

例

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]); // countが変化したときのみタイトルを更新する

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

export default Example;

上記のコードでは、useStateを使用してcountの状態を管理し、useEffectを使用してページのタイトルを更新し、シンプルなボタンでcountを増加させています。

Hooksを使用すると、より簡潔で再利用しやすいコンポーネントコードを記述できます。

Hooksを使用すると、コンポーネントロジックのテストも簡単になります。各Hookのロジックをコンポーネントにラップせずに個別にテストできるからです。

さらに、Hooksはカスタマイズにも対応しています。独自のHooksを作成して複雑なロジックをカプセル化し、複数のコンポーネントで再利用できます。

その他の拡張