この記事ではReactにおけるスプレッド構文の使い方を解説します。
Reactにおいて、スプレッド構文は主にstateが保持するオブジェクトや配列を更新する際に使われます。
1. オブジェクトのスプレッド構文
以下はスプレッド構文を使っていない例。
Reactではstateのオブジェクトを直接変更することは非推奨なので、setPerson()
でfirstName
, lastName
, age
を全て書く必要がある。
import { useState } from 'react'; export default function Form() { const [person, setPerson] = useState({ firstName: 'ichoro', lastName: 'suzuki', age: 8 }); function handleFirstNameChange(e) { setPerson({ firstName: e.target.value, lastName: person.lastName, // ここが冗長 age: person.age // ここが冗長 }); } function handleLastNameChange(e) { setPerson({ firstName: person.firstName, // ここが冗長 lastName: e.target.value, age: person.age // ここが冗長 }); } function handleAgeChange(e) { setPerson({ firstName: person.firstName, // ここが冗長 lastName: person.lastName, // ここが冗長 age: e.target.value }); } return ( <> <label> First name: <input value={person.firstName} onChange={handleFirstNameChange} /> </label> <label> Last name: <input value={person.lastName} onChange={handleLastNameChange} /> </label> <label> Age: <input value={person.age} onChange={handleAgeChange} /> </label> <p> {person.firstName}{' '} {person.lastName}{' '} ({person.age}) </p> </> ); }
これを、スプレッド構文を使って書くと以下のようになる。
import { useState } from 'react'; export default function Form() { const [person, setPerson] = useState({ firstName: 'ichoro', lastName: 'suzuki', age: 8 }); function handleFirstNameChange(e) { setPerson({ ...person, // スッキリ firstName: e.target.value }); } function handleLastNameChange(e) { setPerson({ ...person, // スッキリ lastName: e.target.value }); } function handleAgeChange(e) { setPerson({ ...person, // スッキリ age: e.target.value }); } // 省略 }
さらにComputed property namesを使うとイベントハンドラが一つで済む。
import { useState } from 'react'; export default function Form() { const [person, setPerson] = useState({ firstName: 'ichoro', lastName: 'suzuki', age: 8 }); function handleChange(e) { setPerson({ ...person, [e.target.name]: e.target.value // Computed property names }); } return ( <> <label> First name: <input name="firstName" value={person.firstName} onChange={handleChange} /> </label> <label> Last name: <input name="lastName" value={person.lastName} onChange={handleChange} /> </label> <label> Age: <input name="age" value={person.age} onChange={handleChange} /> </label> <p> {person.firstName}{' '} {person.lastName}{' '} ({person.age}) </p> </> ); }
ネストしたオブジェクトの場合
import { useState } from 'react'; export default function Form() { const [person, setPerson] = useState({ name: 'Ichiro Suzuki', profile: { age: 8, city: 'Seattle', hobby: 'soccer', } }); function handleNameChange(e) { setPerson({ ...person, name: e.target.value }); } function handleAgeChange(e) { setPerson({ ...person, profile: { ...person.profile, age: e.target.value } }); } function handleCityChange(e) { setPerson({ ...person, profile: { ...person.profile, city: e.target.value } }); } function handleHobbyChange(e) { setPerson({ ...person, profile: { ...person.profile, hobby: e.target.value } }); } return ( <> <label> Name: <input value={person.name} onChange={handleNameChange} /> </label> <label> Age: <input value={person.profile.age} onChange={handleAgeChange} /> </label> <label> City: <input value={person.profile.city} onChange={handleCityChange} /> </label> <label> Hobby: <input value={person.profile.hobby} onChange={handleHobbyChange} /> </label> <p> {person.name} is {person.profile.age} years old, lives in {person.profile.city}, and likes {person.profile.hobby}. </p> </> ); }
2. 配列のスプレッド構文
stateの配列もオブジェクトと同様に直接編集してはいけないので、スプレッド構文を使って新しい配列を作成して、それをstateに設定する。
import { useState } from 'react'; let nextId = 0; export default function List() { const [name, setName] = useState(''); const [foods, setFoods] = useState([]); return ( <> <h1>Foods:</h1> <input value={name} onChange={e => setName(e.target.value)} /> <button onClick={() => { setFoods([ ...foods, { id: nextId++, name: name } ]); setName(''); }}>Add</button> <ul> {foods.map(food => ( <li key={food.id}>{food.name}</li> ))} </ul> </> ); }
【参考】