Reactフックを使って、状態管理、データ取得、グローバルなデータ共有を簡単に実現!
初心者向けにuseState、useEffect、useContextを解説します。
Reactは、効率的にUIを作成するためのJavaScriptライブラリです。その中でも「フック(Hooks)」は非常に重要な役割を果たしています。Reactフックを使えば、状態管理やデータの取得、そしてグローバルな状態の共有が簡単に行えるようになります。
1【useState】
useState
は、Reactでコンポーネントに「状態」を持たせるためのフックです。例えば、ボタンをクリックしてカウンターの数値を増やす場合や、フォームの入力値を保持する場合に便利です。
以下に簡単なカウンターコンポーネントを紹介します。
// Counter.jsx
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div style={{ textAlign: "center", marginTop: "20px" }}>
<h2>useStateでカウントアップ</h2>
<p style={{ fontSize: "24px" }}>カウント: {count}</p>
<button
onClick={() => setCount(count + 1)}
style={{
padding: "10px 20px",
fontSize: "16px",
backgroundColor: "#007BFF",
color: "white",
border: "none",
borderRadius: "5px",
cursor: "pointer",
}}
>
カウントアップ
</button>
</div>
);
}
export default Counter;
- useState(0)
useState
に渡した値(ここでは0
)が初期値になります。この例では、初期のcount
の値は0です。
- 更新関数 setCount
setCount
はcount
の値を変更するために使います。
- 例えば、
setCount(count + 1)
を呼ぶと、count
が1増加します。
- イベントハンドラ
- ボタンの
onClick
イベントでsetCount
を呼ぶことで、ユーザーがボタンをクリックするたびにカウントが1増えるようにしています。
これで「カウントアップ」の機能が完成しました。useState
を使うと、リアルタイムで画面に変化を反映するインタラクティブな要素を簡単に作れることがわかりますね。
2【useEffect】
useEffect
は、データの取得、タイマーのセット、イベントリスナーの追加といった「副作用」を管理するためのフックです。初回表示時や、指定したデータが変わるたびに実行する処理を制御できます。
以下に簡単なタイマーコンポーネントを紹介します。
// Timer.jsx
import React, { useState, useEffect } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => clearInterval(interval); // クリーンアップ
}, []); // 初回マウント時のみ実行
return (
<div style={{ textAlign: "center", marginTop: "20px" }}>
<h2>useEffectでタイマー</h2>
<p style={{ fontSize: "24px" }}>経過時間: {seconds}秒</p>
</div>
);
}
export default Timer;
- useEffect(() => {…}, [])
useEffect
の第一引数には実行したい関数を、第二引数には「依存配列」を渡します。
- ここでは空の配列
[]
を指定しているため、初回レンダリング時に一度だけ実行され、interval
が設定されます。
- 依存配列
- 依存配列に値を指定すると、その値が変わるたびに
useEffect
内の処理が再実行されます。
- クリーンアップ関数
return
で関数を返すことで、コンポーネントが削除(アンマウント)された時にclearInterval
が実行され、タイマーを解除します。
この例では、タイマーが1秒ごとにカウントを増やし、コンポーネントが削除されるときにタイマーが解除されています。
3【useContext】
useContext
を使うと、アプリ全体で共通の情報を簡単に参照できます。例えば、テーマ(ダークモードやライトモード)やログイン情報をアプリのどのコンポーネントでも利用したい場合に使用できます。
以下に、テーマを各コンポーネント
//ThemeContext.jsx
import React, { createContext } from "react";
export const ThemeContext = createContext();
export function ThemeProvider({ children }) {
const theme = "dark"; // グローバルテーマを指定
return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>;
}
//App.jsx
import React, { useContext } from "react";
import { ThemeProvider, ThemeContext } from "./ThemeContext";
function ThemedComponent() {
const theme = useContext(ThemeContext);
const styles =
theme === "dark"
? { backgroundColor: "#333", color: "white", padding: "20px" }
: { backgroundColor: "white", color: "#333", padding: "20px" };
return (
<div style={styles}>
<h2>useContextでテーマを適用</h2>
<p>現在のテーマ: {theme}</p>
</div>
);
}
function App() {
return (
<ThemeProvider>
<ThemedComponent />
</ThemeProvider>
);
}
export default App;
- createContextでコンテキストを作成
ThemeContext
というコンテキストを作成しました。このコンテキストは"light"
(ライトテーマ)をデフォルト値としています。
- Providerでコンテキストの値を提供
ThemeContext.Provider
のvalue
属性に設定した値が、useContext
で取得できるようになります。ここでは"dark"
が提供されています。
- useContextで値を取得
ThemedComponent
内でuseContext(ThemeContext)
を使うと、ThemeContext
に設定された値(ここでは"dark"
)を直接取得できます。
この例では、App
内の全ての子コンポーネントが、ThemeContext
を通じてテーマの値を取得できるようになり、簡単にテーマの切り替えが可能になります。つまりReactの特徴の一つでもあるpropsを使用したデータの受け渡しを使用することなくコンポーネント間でデータの受け渡しができるということですね。深い階層のコンポーネントにデータを渡す時に便利です。
まとめ
useState
: 個別コンポーネントの状態を管理。カウンターのようなシンプルなアプリに最適。
useEffect
: データ取得やタイマーの管理。副作用処理を簡潔に記述可能。
useContext
: グローバルな状態の共有と管理に便利。
これらのフックを活用することで、状態管理やデータの取得がよりスムーズに行えます。
他にも、さまざまなフックが存在するので気になる方は、以下のサイトを見てみるのも面白いかもしれません。
https://ja.react.dev/reference/react/hooks