React カスタムフック:機能拡張とサードパーティライブラリ活用術
React カスタムフックと通常の関数の違い
カスタムフックとは?
カスタムフックは、React の状態とライフサイクルを利用して、コンポーネント間で共有できるロジックを作成する関数です。 use
プレフィックスで始まり、他のフックを呼び出すことができます。
通常の関数とは?
通常の関数は、React に特化したものではなく、JavaScript の標準的な関数です。状態やライフサイクルにアクセスすることはできず、コンポーネント間で共有することは想定されていません。
いつどちらを使用すべきか?
以下の表は、カスタムフックと通常の関数の使い分けの指針です。
状況 | カスタムフックを使用する | 通常の関数を使用する |
---|---|---|
状態やライフサイクルにアクセスが必要 | ◯ | × |
ロジックを複数のコンポーネントで共有したい | ◯ | × |
React の特殊な機能を利用する必要がある | ◯ | × |
単純なロジックで、コンポーネント間で共有する必要がない | × | ◯ |
- テストのしやすさ
カスタムフックは単体テストしやすいように設計されています。これは、コードの品質と信頼性を向上させるのに役立ちます。 - コードの分割
カスタムフックを使用すると、複雑なロジックを小さな再利用可能な部分に分割できます。これにより、コードが読みやすくなり、理解しやすくなります。 - コードの再利用性
カスタムフックを使用すると、共通のロジックを別のコンポーネントで簡単に再利用できます。これにより、コードが簡潔になり、保守が容易になります。
以下の例は、カウンタをのカスタムフックです。
function useCounter(initialValue) {
const [count, setCount] = useState(initialValue);
return {
count,
increment: () => setCount(count + 1),
decrement: () => setCount(count - 1),
};
}
このフックは、count
と 2 つのメソッド (increment
と decrement
) を返します。このフックをコンポーネントで使用するには、次のようにします。
const MyComponent = () => {
const { count, increment, decrement } = useCounter(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={increment}>増やす</button>
<button onClick={decrement}>減らす</button>
</div>
);
};
このコンポーネントは、useCounter
フックから返された count
、increment
、decrement
を使用してカウンタを表示し、操作します。
カスタムフックを使用した実装
function useCounter(initialValue) {
const [count, setCount] = useState(initialValue);
return {
count,
increment: () => setCount(count + 1),
decrement: () => setCount(count - 1),
};
}
const MyComponent = () => {
const { count, increment, decrement } = useCounter(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={increment}>増やす</button>
<button onClick={decrement}>減らす</button>
</div>
);
};
解説
useCounter
カスタムフックは、useState
フックを使用してcount
ステートと、それを操作するためのincrement
とdecrement
メソッドを定義します。
通常の関数を使用した実装
function Counter(props) {
const [count, setCount] = useState(props.initialValue);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>増やす</button>
<button onClick={() => setCount(count - 1)}>減らす</button>
</div>
);
}
const MyComponent = () => {
return <Counter initialValue={0} />;
};
Counter
関数は、initialValue
プロップを受け取り、useState
フックを使用してcount
ステートを定義します。Counter
関数は、カウンタの表示と操作のためのボタンを含む JSX を返します。MyComponent
コンポーネントは、Counter
関数をinitialValue
プロップ 0 で呼び出して、カウンタコンポーネントをレンダリングします。
比較
項目 | カスタムフック | 通常の関数 |
---|---|---|
状態管理 | useState フックを使用 | useState フックを使用 |
ロジックの再利用性 | 他のコンポーネントで再利用可能 | 再利用するには、コンポーネントとしてラップする必要がある |
コードの分割 | ロジックを小さな部分に分割できる | ロジックをコンポーネントにカプセル化する必要がある |
テストのしやすさ | 単体テストしやすい | コンポーネントとしてテストする必要がある |
- 通常の関数は、シンプルなロジックや、コンポーネントとしてラップして再利用する予定がないロジックに適しています。
- カスタムフックは、状態やライフサイクルにアクセスする必要があるロジック、または複数のコンポーネントで共有するロジックに適しています。
このパターンは、複雑なロジックを持つカスタムフックを作成する場合に役立ちます。useReducer
フックを使用して、状態の更新を処理する reducer 関数を定義できます。
function useCounter(initialValue) {
const [state, dispatch] = useReducer(counterReducer, { count: initialValue });
return {
count: state.count,
increment: () => dispatch({ type: 'INCREMENT' }),
decrement: () => dispatch({ type: 'DECREMENT' }),
};
}
const counterReducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
};
Context API を使用したカスタムフック
このパターンは、グローバルな状態を管理する必要があるカスタムフックを作成する場合に役立ちます。useContext
フックを使用して、Context プロバイダから値を取得できます。
const CounterContext = createContext({ count: 0, increment: () => {}, decrement: () => {} });
function CounterProvider({ children }) {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
const value = { count, increment, decrement };
return (
<CounterContext.Provider value={value}>
{children}
</CounterContext.Provider>
);
}
function useCounter() {
const context = useContext(CounterContext);
return context;
}
const MyComponent = () => {
const { count, increment, decrement } = useCounter();
return (
<div>
<p>カウント: {count}</p>
<button onClick={increment}>増やす</button>
<button onClick={decrement}>減らす</button>
</div>
);
};
カスタムフックの合成
このパターンは、複数のカスタムフックを組み合わせることで、より複雑な機能を持つカスタムフックを作成する場合に役立ちます。
function useColor() {
const [color, setColor] = useState('red');
return {
color,
setColor,
};
}
function useFontSize() {
const [fontSize, setFontSize] = useState(16);
return {
fontSize,
setFontSize,
};
}
function useTitle() {
const { color } = useColor();
const { fontSize } = useFontSize();
return `タイトル (${color}, ${fontSize}px)`;
}
サードパーティライブラリの使用
React カスタムフックを開発するためのサードパーティライブラリがいくつかあります。これらのライブラリは、追加機能やユーティリティを提供することで、カスタムフックの開発を容易にすることができます。
これらの方法は、それぞれ異なる利点と欠点があります。状況に合わせて適切な方法を選択することが重要です。
reactjs react-hooks