Reactのstate は、コンポーネント内で管理される動的なデータや状態を指します。これにより、コンポーネントが持つデータやその表示内容を動的に変更できるようになります。
state は、ユーザーの操作やその他のイベント(APIからのデータ取得など)に応じて変更されるデータを格納し、データが変更されるとReactは自動的にコンポーネントを再レンダリングしてUIを更新します。
Reactのstateの特徴
-
動的なデータ管理:
-
stateは、コンポーネント内で動的に変わるデータを管理します。例えば、ボタンクリックでカウントが増える、入力フィールドのテキストが変わるといった動作に対応します。
-
-
コンポーネントごとに独立:
-
各コンポーネントは独自のstateを持つことができます。親子コンポーネントで props を通じてデータを共有することもできますが、state 自体はそのコンポーネントだけに閉じたデータです。
-
-
再レンダリングのトリガー:
-
stateが更新されると、Reactはその変更を検知し、自動的に再レンダリングを行ってUIを更新します。
-
useState フックを使ったstateの設定
Reactの関数コンポーネントでstateを使うには、useStateというフックを使用します。このフックは、初期状態とその状態を更新する関数を返します。
例: 簡単なカウンターコンポーネント
import React, { useState } from 'react';
const Counter = () => {
// カウントの状態を定義(初期値は0)
const [count, setCount] = useState(0);
// ボタンがクリックされたときにカウントを増やす関数
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>現在のカウント: {count}</p>
<button onClick={handleClick}>カウントを増やす</button>
</div>
);
};
export default Counter;
1. useStateの使い方
useState は、次のように初期状態を渡すと、現在の state の値と、state を更新するための関数を返します。
const [state, setState] = useState(初期値);
-
state: 現在の状態を保持する変数。
-
setState: 状態を更新するための関数。この関数を呼び出すことで、状態が変わり、再レンダリングが発生します。
2. 状態の更新
setState関数を使ってstateを更新します。更新すると、Reactがそのコンポーネントを再レンダリングし、新しい状態に基づいてUIが自動的に更新されます。
例では、handleClick関数がボタンをクリックするたびにカウント(count)を1増やしています。
3. Stateは同期的ではない
setStateで状態を更新すると、次のレンダリングサイクルで反映されます。これは非同期的に処理されるため、複数の setState が連続で呼ばれた場合には注意が必要です。
例: 入力フォームでのstate管理
ユーザーの入力を追跡するために state を使う例です。
import React, { useState } from 'react';
const InputForm = () => {
const [text, setText] = useState('');
const handleChange = (event) => {
setText(event.target.value); // 入力された値をstateにセット
};
return (
<div>
<input type="text" value={text} onChange={handleChange} />
<p>入力されたテキスト: {text}</p>
</div>
);
};
export default InputForm;
stateの注意点
-
独立した管理: 各コンポーネントが独自の state を持ち、それぞれのインスタンスは独立して動作します。
-
リセット: コンポーネントがアンマウントされると、その state も一緒にリセットされます。
-
state の共有: 親コンポーネントの state を props として子に渡すことで、子コンポーネントでもその状態を利用できます。
-
state の維持: 再レンダリングの条件や、memo によって、state の維持・再レンダリングの制御が可能です。
1. コンポーネントごとに独立したstate管理
Reactでは、各コンポーネントが独自の state を持ちます。これは、同じコンポーネントでも複数のインスタンスが存在する場合、それぞれが独自の state を持っており、他のインスタンスの state に影響を与えません。
例
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>増やす</button>
</div>
);
};
const App = () => {
return (
<div>
<Counter /> {/* 1つ目のカウンター */}
<Counter /> {/* 2つ目のカウンター */}
</div>
);
};
上記の例では、Counter コンポーネントが2つレンダリングされていても、それぞれが独立して state を管理しています。1つ目の Counter のボタンを押しても、2つ目には影響がありません。
2. コンポーネントが破棄されるとstateは初期化される
Reactでは、コンポーネントがアンマウント(削除)されると、その state も一緒に消滅します。そのため、コンポーネントが再度レンダリングされたとき、state は初期化されます。
例
const ToggleCounter = () => {
const [visible, setVisible] = useState(true);
return (
<div>
<button onClick={() => setVisible(!visible)}>表示切替</button>
{visible && <Counter />}
</div>
);
};
Counter コンポーネントが表示されている間に state を更新しても、一度非表示にして再度表示すると state はリセットされ、カウントが初期状態に戻ります。
3. stateを親から子にprops経由で渡し利用する
state を 親コンポーネントで管理し、それを props として子コンポーネントに渡すことで、子コンポーネントでもその state を利用することができます。これは、データを一元管理したい場合や、状態を複数のコンポーネントで共有したいときに便利です。
例
const ParentComponent = () => {
const [count, setCount] = useState(0);
return (
<div>
<ChildComponent count={count} />
<button onClick={() => setCount(count + 1)}>増やす</button>
</div>
);
};
const ChildComponent = ({ count }) => {
return <p>カウント: {count}</p>;
};
この場合、ParentComponent で管理している state を ChildComponent に props として渡しています。これにより、ChildComponent は親の state を参照できるようになります。
4. 特定の条件下でstateが保持される
state が維持されるかどうかは、そのコンポーネントがどのように管理されているか、または再レンダリングされる条件に依存します。具体的には、親コンポーネントが再レンダリングされたときに、子コンポーネントも再レンダリングされるかが影響します。
メモ化による state の保持例
Reactの memo 関数を使うと、親コンポーネントが再レンダリングされても、props が変更されない限り、子コンポーネントの state は再レンダリングされません。これにより、子コンポーネントの state を保持できます。
const ChildComponent = React.memo(({ count }) => {
return <p>カウント: {count}</p>;
});
これにより、子コンポーネントは props が変わらない限り再レンダリングされないため、state が保持されます。
まとめ
-
state はコンポーネント内の動的データを管理し、UIを動的に更新するために使用します。
-
useState フックを使って、状態を定義し、更新する関数を利用します。
-
状態が更新されると、自動的に再レンダリングが発生してUIが最新の状態を反映します。
-
Reactの状態管理は、インタラクティブなUIを構築するための重要な要素です。
コメント