ReactでuseStateを使ったオブジェクト・配列の扱い方完全ガイド!初心者でもわかるReactフック
生徒
「ReactでuseStateを使ってオブジェクトや配列を管理する方法はありますか?」
先生
「はい、useStateは文字列や数値だけでなく、オブジェクトや配列も扱えます。」
生徒
「でも、値を直接変更するのはダメって聞いたんですが…」
先生
「その通りです。Reactでは状態を直接変更すると再レンダリングが行われないので、必ずコピーして更新する必要があります。」
生徒
「なるほど、コピーして更新するんですね。具体的な書き方を教えてください。」
先生
「では、オブジェクトと配列のそれぞれの例を見ていきましょう。」
1. オブジェクトをuseStateで扱う方法
ReactのuseStateでオブジェクトを管理するときは、現在の状態をそのまま書き換えず、 「スプレッド構文(...)」を使って新しいオブジェクトを作り直すことがとても大切です。 状態を直接変更するとReactが変化を検知できず、画面が更新されないことがあるためです。 初心者の方は「オブジェクトは必ずコピーしてから更新する」という意識を持っておくと、 複数の値をまとめて扱う場面でも安心して使えるようになります。 ここでは、もっとイメージしやすいように、名前と年齢を持つシンプルなオブジェクトを例に見ていきましょう。
import React, { useState } from "react";
function App() {
const [user, setUser] = useState({ name: "太郎", age: 20 });
const changeName = () => {
// オブジェクトをコピーしつつ、nameだけを更新する
setUser({ ...user, name: "次郎" });
};
const incrementAge = () => {
// 年齢を1つ増やす更新も同じ考え方で行える
setUser({ ...user, age: user.age + 1 });
};
return (
<div>
<h1>{user.name} - {user.age}歳</h1>
<button onClick={changeName}>名前を変更</button>
<button onClick={incrementAge} style={{ marginLeft: "8px" }}>
年齢を1つ増やす
</button>
</div>
);
}
export default App;
このように、オブジェクトを扱うときもスプレッド構文でコピーして必要な項目だけ更新すれば、 Reactが正しく変化を検知し再レンダリングしてくれます。 「複数の値をまとめて管理したいときはオブジェクトを使う」という考え方と、 「必ずコピーしてから更新する」という流れをセットで覚えておくと、 フォーム入力やユーザー情報管理などの実装で役に立ちます。
2. 配列をuseStateで扱う方法
配列をuseStateで管理するときも、オブジェクトと同じように「元の配列をそのまま書き換えない」ことが大事なルールになります。 JavaScriptではpushやpopなどで配列を直接変更できますが、Reactの状態として使っている配列に対してこれを行うと、 状態の中身は変わっているのにReactが変化に気づかず、画面が更新されない原因になります。 そのため、配列を扱うときは常に一度コピーを作り、その新しい配列をuseStateの更新関数に渡すという流れを意識しましょう。 よく使われるのがスプレッド構文(...)やslice・filterといった配列操作です。
import React, { useState } from "react";
function App() {
const [items, setItems] = useState(["りんご", "みかん"]);
// 配列の末尾にフルーツを1つ追加する
const addItem = () => {
setItems([...items, "バナナ"]);
};
// 配列の最後の要素を取り除く
const removeLastItem = () => {
// sliceを使って新しい配列を作り直す
setItems(items.slice(0, -1));
};
return (
<div>
<h2>フルーツリスト</h2>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
<button onClick={addItem}>バナナを追加</button>
<button onClick={removeLastItem} style={{ marginLeft: "8px" }}>
最後のフルーツを削除
</button>
</div>
);
}
export default App;
このサンプルでは、追加も削除も「新しい配列を作ってからsetItemsに渡す」という同じ考え方で実装しています。
スプレッド構文で[...items, "バナナ"]のように書けば、元の配列を壊さずに要素を足した新しい配列が作れますし、
items.slice(0, -1)のように書けば、最後の要素を除いた新しい配列を作ることができます。
Reactで配列の状態を扱うときは、pushやpopを直接使うのではなく、
「スプレッド構文+map / filter / slice / concatなどの配列メソッドで新しい配列を返す」というパターンに慣れておくと、
todoリストや買い物リスト、タグ一覧など、実用的なコンポーネントを安心して作れるようになります。
3. オブジェクトや配列更新の注意点
- 状態を直接変更せず、必ずコピーして更新する
- スプレッド構文を使うと既存の値を壊さずに更新できる
- 配列を更新するときはmapやfilterを使うと便利
- Reactは新しいオブジェクトや配列に置き換えた時のみ再レンダリングされる
4. 実践例:オブジェクトと配列を組み合わせる
function App() {
const [user, setUser] = useState({ name: "太郎", hobbies: ["読書", "ゲーム"] });
const addHobby = () => {
setUser({ ...user, hobbies: [...user.hobbies, "スポーツ"] });
};
return (
<div>
<h1>{user.name}</h1>
<ul>
{user.hobbies.map((hobby, index) => (
<li key={index}>{hobby}</li>
))}
</ul>
<button onClick={addHobby}>趣味を追加</button>
</div>
);
}
5. ポイント整理
- useStateはオブジェクトや配列も扱える
- 直接変更せず、スプレッド構文やコピーで更新する
- map, filter, concatなどの配列操作を活用すると便利
- 複雑な状態は状態管理の可読性を意識して設計する
まとめ
ReactでuseStateを使ってオブジェクトや配列を管理する方法を学んできましたが、改めて振り返ると、状態管理はReactを理解する上で非常に重要な基礎であり、アプリケーション全体の安定性や動作の滑らかさに直結する大切な仕組みだと分かります。とくに初心者の方がつまずきやすい「直接状態を書き換えてしまう」という問題は、画面が更新されない原因になりやすいため、必ず新しいオブジェクトや配列を作成して状態を更新するというReact特有の考え方を早い段階で身につけることが大切です。
オブジェクトの更新ではスプレッド構文を活用することで、既存の値を壊さずに必要な項目だけを変更でき、配列の更新ではmapやfilterなどのメソッドを組み合わせることで、新しい配列を作りながら柔軟に操作できます。また、配列とオブジェクトが入れ子になっている複雑な状態でも、基本は同じで「上の階層から順番にコピーして更新する」というシンプルな考え方を守るだけで安定した状態管理ができます。
まとめとして、Reactの状態管理は難しそうに見えても、コピーして更新するというルールを守れば一気に扱いやすくなり、フォーム入力、ユーザー情報管理、リスト表示など実際のアプリ開発でよく使う場面で必ず役に立ちます。以下に振り返りとして簡単なサンプルを示しながらポイントを再確認します。
オブジェクトと配列を合わせた簡単サンプル
function App() {
const [profile, setProfile] = useState({
name: "花子",
skills: ["デザイン", "コーディング"]
});
const addSkill = () => {
setProfile({
...profile,
skills: [...profile.skills, "テスト"]
});
};
return (
<div>
<h2>{profile.name}さんのスキル一覧</h2>
<ul>
{profile.skills.map((skill, index) => (
<li key={index}>{skill}</li>
))}
</ul>
<button onClick={addSkill}>スキルを追加</button>
</div>
);
}
このように、スプレッド構文を使うことで複雑な状態であっても安全に更新できることが分かります。ReactのuseStateは初心者にとって最初の大きな壁のように感じることもありますが、考え方さえ理解できれば、どんなアプリケーションでも応用できる非常に強力な仕組みです。配列やオブジェクトが絡む状態管理は、実務でも頻繁に登場するため、今回の学びを活かして実際のアプリ作りに挑戦していくと理解がより深まります。
生徒
「今日の内容で、Reactの状態管理が前より分かりやすくなった気がします。特にオブジェクトや配列をコピーして更新する理由が理解できました。」
先生
「その調子です。Reactは再レンダリングの仕組みを理解すると、一気に書き方が安定してきます。とくにスプレッド構文の使い方は、これからReactを書く上で避けて通れない大切なものです。」
生徒
「確かに、コピーしてから更新するだけで再レンダリングが正しく動くと分かれば、複雑なデータでも扱えそうです。配列のmapやfilterを使うところも面白かったです。」
先生
「良い気づきですね。配列操作はReactの表示ロジックとも相性が良いので、どんどん使って慣れていきましょう。次のステップとして、フォーム入力や複数のコンポーネントで状態を共有するやり方も学んでいくと、さらに理解が深まりますよ。」
生徒
「ありがとうございます!まずは今回の内容を使って、小さなアプリを自分で作ってみます。」