Reactでアプリを作ってみようとすると、必ず出会うのが「state(ステート)」です。
初心者の方にとっては「stateって何?」「どうやって使うの?」と感じるかもしれませんが、
この記事を読むことで、Reactのstateとその使い方について理解できるようになります。
少しずつ一緒に学んでいきましょう!
stateとは?
まずは「state」が何なのかを見てみましょう。
stateとは、コンポーネント内で管理される「状態」のことです。
例えば、ユーザーが入力したデータや、ボタンをクリックした回数、
ロードの進捗状況など、アプリケーションのさまざまな「変わる可能性がある値」を管理するために使います。
stateを使うと何がどう良いの?
Reactのstateを使うと、
画面の一部だけをサッと変えたり、ユーザーの操作にすぐ反応したりできるようになります。
これがないとどうなるかというと、
例えば「ボタンを押すと数が増えるカウンター」を作るときに、
ボタンを押すたびにページ全体をリロードするような動きになってしまいます。
これではさっさとポチポチ押したいのに、いちいちページリロードされて鬱陶しいですよね。
処理を待つ時間も発生しますし、更新不要な部分まで再度読み込むことになります。
が、stateを使うと、
値が変わったときにReactが「どこを更新すればいいか」を自動的に判断して、
画面の必要な部分だけをパッと更新してくれます。
たとえばカウント数をstateで管理している場合、
ボタンを押して数が増えたとき、カウントの表示部分だけが自動で更新されるのです。
ページ全体をリロードする必要がないので、表示がとても速くなります。
これは「SPA(シングルページアプリケーション)」という仕組みと繋がっています。
通常のページだと「画面全体が切り替わる」ことが多いのですが、
Reactとstateを使えば、必要な部分だけを更新するため、
ユーザーにとってはページが一瞬で反応するように感じられ、使いやすいアプリが作れるのです。
SPA(Single Page Application)とは
ページ全体をリロードせずに、一つのページ内で必要な部分だけを動的に書き換えて操作できるアプリケーションのこと。
例えば、通常のWebサイトではリンクをクリックすると新しいページが読み込まれ、画面が全部リロードされますが、SPAでは最初にページ全体を読み込んでしまい、その後はJavaScriptを使って「必要なデータ」だけを取り込み、画面の一部だけを更新します。そのため、操作がスムーズで、アプリのような使いやすさを感じられるのが特徴です。
stateを使えば、と解説していますが、厳密にはstateは値を保持するもので、更新には仮想DOMという仕組みをあわせて使うことで部分的な更新を実現しています。
仮想DOMについてはこちらの記事も参考にしてみてください。
useStateを使ってstateを設定してみよう!
それではそんなstateを実際に使ってみましょう。
Reactでstateを使うには、React Hooksの一つであるuseStateを使います。
useStateは、stateを作成し、そのstateを更新するための関数を提供してくれます。
useStateの基本的な使い方
まずは、カウンターの例を使って、useState
の基本的な使い方を見てみましょう。
import React, { useState } from 'react';
function Counter() {
// countというstateを作成し、初期値は0に設定
const [count, setCount] = useState(0);
// ボタンをクリックしたらカウントを増やす関数
const handleIncrement = () => {
setCount(count + 1);
};
return (
<div>
<p>カウント: {count}</p>
<button onClick={handleIncrement}>増やす</button>
</div>
);
}
export default Counter;
JSXコードの解説
上記のコードでそれぞれ何をしているのでしょうか?
ひとつずつ見ていきます。
useState(0)でstateを初期化する
useState
はReactのHookの一つで、コンポーネントにstateを追加するための関数です。
ここで引数に0
を指定していますが、これはcount
の初期値として0を設定しているということです。
最初はとりあえず「0」を入れてるわけね
[count, setCount]によるstateと更新関数の取得
useState
は配列を返し、
その配列の1つ目の要素が現在のstateの値、2つ目がそのstateを更新するための関数になります。
この2つは必ずセットと覚えておいていいでしょう。
また、慣習的に、stateの値の名前に「count」という単語を使うなら、その更新用関数は「setCount」とします。
state名が「userName」なら、更新用関数は「setUserName」とします。
state名が「isVisible」なら、更新用関数は「setIsVisible」となるイメージですね。
命名自体は自由にできますが、基本的には慣習に沿った命名をすることで、他の開発者にもわかりやすくメンテナンスしやすいコードになります。
setCount(count + 1)によるstateの更新とUIの再レンダリング
setCount
関数はcount
の値を更新するために使われます。
ここでは、ボタンがクリックされるたびにcount
が1増えるように設定されています。
ここでは、setCount関数が呼ばれcount(state)の値が変わることで、
そのstateを使用しているコンポーネントが再レンダリングされる仕組みになっています。
これで一連の流れは終わりです。
stateに数値以外の値を入れる場合
stateは数値だけでなく、文字列やオブジェクト、配列など様々なデータ型を扱うことができます。
ここでは以下にそれぞれの例を紹介しますので、参考までに見てみましょう。
文字列をstateとして管理する
例えば、ユーザーの名前を入力するテキストフィールドを作成する場合、
stateでその文字列を管理することができます。
import React, { useState } from 'react';
function NameInput() {
const [name, setName] = useState(''); // 初期値は空の文字列
const handleChange = (event) => {
setName(event.target.value);
};
return (
<div>
<input type="text" value={name} onChange={handleChange} />
<p>こんにちは、{name}さん!</p>
</div>
);
}
export default NameInput;
JSXオブジェクトをstateとして管理する
オブジェクトをstateとして管理すると、複数の値を一度に管理できます。
例えば、ユーザー情報(名前と年齢)をstateに保存したい場合の例です。
import React, { useState } from 'react';
function UserInfo() {
const [user, setUser] = useState({ name: '', age: '' });
const handleChange = (event) => {
const { name, value } = event.target;
setUser({ ...user, [name]: value });
};
return (
<div>
<input
type="text"
name="name"
placeholder="名前"
value={user.name}
onChange={handleChange}
/>
<input
type="number"
name="age"
placeholder="年齢"
value={user.age}
onChange={handleChange}
/>
<p>こんにちは、{user.name}さん。{user.age}歳ですね!</p>
</div>
);
}
export default UserInfo;
JSX配列をstateとして管理する
配列をstateとして管理する場合、例えば「ToDoリスト」のように、
複数のアイテムを扱う場合に便利です。
import React, { useState } from 'react';
function TodoList() {
const [tasks, setTasks] = useState([]);
const [newTask, setNewTask] = useState('');
const handleAddTask = () => {
setTasks([...tasks, newTask]); // 新しいタスクを追加
setNewTask(''); // 入力をクリア
};
return (
<div>
<input
type="text"
value={newTask}
onChange={(e) => setNewTask(e.target.value)}
placeholder="タスクを入力"
/>
<button onClick={handleAddTask}>追加</button>
<ul>
{tasks.map((task, index) => (
<li key={index}>{task}</li>
))}
</ul>
</div>
);
}
export default TodoList;
JSXstateの更新で気をつけるポイント
stateの更新にはいくつか注意点があります。
特に初心者が気をつけたいポイントをいくつかご紹介します。
1. stateの更新は非同期である
Reactのstate更新は即座に反映されるわけではなく、非同期的に処理されることが多いです。
例えば、複数のsetState
が連続して行われた場合、
期待した結果と異なる場合があるので注意が必要です。
2. 同じstateを複数回更新する場合の工夫
もし同じstateを使って複数の値を変更する場合、
setState
の関数形式を使うと便利です。例えば、カウントを2つ増やしたい場合は以下のように書けます。
setCount((prevCount) => prevCount + 1);
JSXstateの値が保持される期間
ところで、stateが値を保持するのはいつからいつまでなのでしょうか?
stateの値は、コンポーネントが表示されている間(マウントされている間)は保持されますが、
コンポーネントが削除されたり、再作成されたりしたとき(アンマウントされたとき)には破棄されます。
つまり、
コンポーネントが表示されている間はそのコンポーネントのstateが保持され、
画面の切り替えなどで、コンポーネントが再レンダリングされたりする場合は消えちゃうよということです。
まとめ
stateはReactのアプリケーションを「動的」にするために欠かせない要素です。
useState
を使えば、数値や文字列、オブジェクト、配列など様々なデータ型をstateとして管理し、
ユーザーの操作に応じてアプリの表示や動作を変化させることができます。
今回紹介した基本的な使い方や注意点を押さえれば、Reactでの開発がもっと楽しくなるはずです。
今後もstateの使い方に慣れていき、さらに複雑なアプリケーションにもチャレンジしていきましょう!
あざした