【React Hooks】useStateと変数はどっちを使うべき?それぞれのメリットとデメリットを比較解説
React HooksにおけるuseStateと変数の比較:詳細解説
React Hooksは、関数コンポーネントで状態管理を可能にするReact 16.8以降で導入された新機能です。中でも、useState
フックは最も基本的なフックの一つであり、コンポーネント内部の状態を管理するのに役立ちます。
一方、変数はプログラミングにおける基本的な要素であり、値を格納するために使用されます。
一見似ているように見えるuseStateと変数ですが、実は重要な違いがあります。このガイドでは、React HooksにおけるuseStateと変数の違いを詳細に解説し、それぞれの適切な使い分けについて説明します。
状態と変数の違い
まず、状態と変数の違いを明確にすることが重要です。
- 変数
一定期間変わらない値を格納するために使用されます。例えば、関数やコンポーネント内で使用する定数、補助的な計算結果などが該当します。 - 状態
コンポーネントのデータの中で、時間経過とともに変化するものを指します。例えば、カウント値、ボタンの押下状態、フォームに入力された値などが該当します。
useStateフックの特徴
useState
フックは、コンポーネント内部に状態を保持するための関数です。以下の2つの要素を返します。
- 現在の状態値
これは、コンポーネントがレンダリングされる時点での状態の最新値です。 - 状態更新関数
これは、setState
と呼ばれる関数で、状態を更新するために使用されます。
変数の特徴
一方、変数は通常の変数と同様に、値を格納して保持するために使用されます。変数の値は、明示的に変更されない限り、コンポーネントのライフサイクル全体を通して保持されます。
使い分けるポイント
では、いつuseStateを使用し、いつ変数を使用すればよいのでしょうか?
useStateを使用すべきケース
- ユーザーの操作によって更新されるデータを保持する場合
- 時間経過とともに変化するデータを保持する場合
- コンポーネントのレンダリング結果に影響を与えるデータを保持する場合
変数を使用すべきケース
- 補助的な計算結果を保持する場合
- 一定期間変わらないデータを保持する場合
コード例
以下のコード例は、useState
と変数の違いを分かりやすく示しています。
// useStateを使った例
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>カウントアップ</button>
</div>
);
}
// 変数を使った例
function Message() {
const message = 'Hello, world!';
return (
<div>
<p>{message}</p>
</div>
);
}
この例では、Counter
コンポーネントはuseState
を使用してカウント値を状態として保持し、ボタンクリック時に更新しています。一方、Message
コンポーネントは変数を使用してメッセージを保持しており、メッセージはコンポーネントのライフサイクル全体を通して変化しません。
useState
と変数は、それぞれ異なる目的で使用されます。
- 変数は、一定期間変わらないデータを保持するために使用されます。
useState
は、コンポーネント内部の状態を管理するために使用されます。
このコンポーネントは、ボタンをクリックするたびにカウント値を1ずつ増やす機能を提供します。
// カウントアップコンポーネント
function Counter() {
const [count, setCount] = useState(0); // 初期状態を0に設定
return (
<div>
<p>カウント: {count}</p> // 現在の状態値を表示
<button onClick={() => setCount(count + 1)}>カウントアップ</button> // ボタンクリック時に状態を更新
</div>
);
}
メッセージ表示コンポーネント (変数使用)
このコンポーネントは、変数に格納されたメッセージを常に表示します。
// メッセージ表示コンポーネント
function Message() {
const message = 'Hello, world!'; // 変数にメッセージを格納
return (
<div>
<p>{message}</p> // 変数の値を表示
</div>
);
}
コードの実行
上記のコードを実行すると、以下のような画面が表示されます。
- メッセージ表示コンポーネント: メッセージは常に "Hello, world!" と表示されます。
- カウントアップコンポーネント: ボタンをクリックするたびにカウント値が1ずつ増加します。
ポイント
Message
コンポーネントでは、変数にメッセージを格納しています。メッセージはコンポーネントのライフサイクル全体を通して変化しません。Counter
コンポーネントでは、useState
フックを使用してカウント値を状態として保持しています。ボタンクリック時にsetCount
フックを呼び出すことで、状態を更新しています。
- React Hooksには、
useState
以外にも様々なフックが用意されています。それぞれのフックの役割と使い分けについて、詳細を学ぶことをお勧めします。
useReducer
フックは、より複雑な状態管理ロジックを扱う場合に適しています。useState
と異なり、状態更新ロジックをreducer関数として定義することで、より詳細な制御が可能になります。
メリット
- Reduxなどの外部状態管理ライブラリとの連携が容易
- 以前の状態に基づいて新しい状態を計算しやすい
- 複雑な状態更新ロジックを処理しやすい
- シンプルな状態管理にはオーバースペック
useState
よりも複雑で習得難易度が高い
例
function Counter() {
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<p>カウント: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>カウントアップ</button>
</div>
);
}
useContext
useContext
フックは、コンポーネント間で状態を共有する場合に役立ちます。コンテキストAPIと呼ばれる仕組みと連携して使用し、親コンポーネントで提供された状態を子コンポーネントで消費することができます。
- リフトアップとプロップドリリングを回避できる
- グローバルな状態管理に適している
- コンポーネント間で状態を共有しやすい
- 誤った使い方をすると、予期せぬバグが発生する可能性がある
- 複雑なネスト構造になると、状態の追跡が困難になる
// 親コンポーネント
const ThemeContext = React.createContext({ theme: 'light' });
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Counter />
</ThemeContext.Provider>
);
}
// 子コンポーネント
function Counter() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<div>
<p>テーマ: {theme}</p>
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>テーマ切替</button>
</div>
);
}
useRef
- 状態更新ロジックとは独立して処理を実行できる
- パフォーマンスを最適化するのに役立つ
- 複雑な状態管理には不向き
- 状態を直接管理することはできない
function Counter() {
const inputRef = useRef(null);
return (
<div>
<input type="number" ref={inputRef} />
<button onClick={() => {
const value = parseInt(inputRef.current.value);
// 状態更新ロジックを実行
}}>カウント更新</button>
</div>
);
}
上記以外にも、useMemo
、useCallback
、useEffect
などのフックを組み合わせることで、様々な状態管理手法を実現することができます。
javascript node.js reactjs