はじめに
ReactのHooksは関数コンポーネントでの状態管理やライフサイクルの機能を使えるようにする、React 16.8で導入された機能です。
この記事では、Reactの主要なHooksを紹介し、それぞれの基本的な使い方を解説します。
Hooksとは
Hooksは、クラスコンポーネントを書かずに、状態や他のReactの機能を関数コンポーネントで使えるようにする関数です。これにより、より読みやすく、再利用しやすいコンポーネントを作成できます。
useStateについて
useState
は、関数コンポーネントでstateを持たせるためのHookです。
これにより、以前はクラスコンポーネントでしか利用できなかったstateを、関数コンポーネントでも使うことができるようになります。
import React, { useState } from 'react';
function Counter() {
// useStateを使ってstate変数を宣言します
// ここでは`count`というstate変数を0で初期化しています
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
// setCountを使ってcountを更新します
<button onClick={() => setCount(count + 1)}>
Click me!
</button>
</div>
);
}
export default function App() {
return (
<div className="App">
<Counter />
</div>
);
}
この例では、useState
を使って count
という名前のstate変数を作成し、初期値として 0
を設定しています。
setCount
はこの count
を更新するための関数です。ボタンをクリックすると、 count
が1増えるようになっています。
注意点
-
useState
は、コンポーネントのレンダリングごとに同じ順序で呼び出される必要があります。そのため、条件分岐やループの中でuseState
を呼び出すことはできません。 -
useState
に渡す初期値は、コンポーネントの最初のレンダリング時にのみ使用されます。それ以降のレンダリングでは無視されます。
useEffectについて
useEffect
は、コンポーネントがレンダリングされた後に何かしらの処理を行いたい場合に使用します。
これにより、クラスコンポーネントの componentDidMount
、componentDidUpdate
、componentWillUnmount
に相当する処理を実装できます。
import React, { useState, useEffect } from 'react';
function Counter() {
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 function App() {
return (
<div className="App">
<Counter />
</div>
);
}
useEffect
は、第一引数に関数を、第二引数に依存配列(dependency array)を取ります。依存配列に指定された値が変更されたとき、またはコンポーネントがマウントされたとき(依存配列が空の場合)、第一引数の関数が実行されます。
依存配列の使用
useEffect
の第二引数に配列を渡すことで、配列内の値が変更された場合のみエフェクトが実行されるようになります。
useEffect(() => {
// APIを呼び出すなどの副作用を実行
}, [dependency]); // このエフェクトはdependencyが変更されたときのみ実行されます
useContextについて
useContext
はコンテキストオブジェクトを受け取り、そのコンテキストの現在値を返します。これにより、コンポーネントツリー内のどこからでもコンテキストを参照できるようになります。
// ステップ1: ユーザー設定のためのコンテキストを作成
const UserSettingsContext = createContext();
// ステップ2: ユーザー設定を提供するプロバイダーコンポーネント
function UserSettingsProvider({ children }) {
const userSettings = {
username: 'Taro',
theme: 'test'
};
return (
<UserSettingsContext.Provider value={userSettings}>
{children}
</UserSettingsContext.Provider>
);
}
// ユーザープロファイルコンポーネント
function UserProfile() {
// ステップ3: useContextでユーザー設定を取得
const settings = useContext(UserSettingsContext);
return (
<div>
<h1>{settings.username}'s Profile</h1>
<p>Current Theme: {settings.theme}</p>
</div>
);
}
export default function App() {
return (
<div className="App">
<UserSettingsProvider>
<UserProfile />
</UserSettingsProvider>
</div>
);
}
-
ステップ1:
createContext()
を使用して、新しいコンテキストUserSettingsContext
を作成します。これはユーザー設定を格納するためのものです。 -
ステップ2:
UserSettingsProvider
というプロバイダーコンポーネントを作成し、UserSettingsContext.Provider
を使用して、ユーザー設定の値をコンポーネントツリーに提供します。このコンポーネントはどの子コンポーネントも受け取ることができます。 -
ステップ3:
useContext(UserSettingsContext)
を使用して、ユーザー設定の現在の値にアクセスします。これにより、UserProfile
コンポーネント内でユーザー設定が直接使用できます。
useContext
を使用することで、コンポーネントツリーを通じてデータを簡単に渡すことができます。これにより、propsのドリリング(親コンポーネントから子コンポーネントへと、多層にわたってpropsを渡していくプロセス)を避けることができ、コードの可読性と保守性を向上させることができます。
useReducerについて
useReducer
は、状態管理に関して useState
よりも柔軟なアプローチを提供します。特に大規模なコンポーネントや複雑な状態ロジックを持つ場合に便利です。このフックを使うと、状態の更新ロジックをコンポーネントから分離し、よりテストしやすく、読みやすいコードを書くことができます。
基本的な使い方
useReducer
は、現在の状態とそれを更新するためのアクションを引数に取る reducer
関数を使用します。これはReduxのreducerに似ていますが、Reduxを使うほどではない小規模なケースに適しています。
import React, { useReducer } from 'react';
// 初期状態を定義
const initialState = { count: 0 };
// reducer関数を定義
// stateとactionを受け取り、新しい状態を返す
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
function Counter() {
// useReducerを使って状態とディスパッチ関数を取得
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</>
);
}
export default function App() {
return (
<div className="App">
<Counter />
</div>
);
}
この例では、Counter
コンポーネント内で useReducer
を使っています。
reducer
関数は、現在の状態とアクションオブジェクトを受け取り、新しい状態を返します。
このパターンはReduxで一般的ですが、ここではReactのコンテキスト内で完結しています。
最後に
ここまで読んでくださってありがとうございました。
ここで紹介できたのは一部のみですが、少しでもお役に立てば幸いです。
他にもHooksはたくさんありますので、気になった方はぜひ調べてみてください!