スプレッド構文を使うようになってからコードの可読性が上がったように感じたので、
どのようなところで使っているのかまとめます。
スプレッド構文とは
// Array
const odd = [1, 3]
const even = [2, 4]
const numbers = [...odd, ...even]
console.log(numbers) // [1, 3, 2, 4]
// Object
const name = {first: "Tanaka", last: "Taro"}
const age = {age: 27}
const profile = {...name, ...age}
console.log(profile) // {first: "Tanaka", last: "Taro", age: 27}
配列やオブジェクトをコピーするだけでなく、マージすることが簡単にできます。
Arrayを見るとわかりますが並び順は変わらないので注意。
配列であればhoge.concat()
オブジェクトであれば、Object.asign()
を使い実現していたことを短い記述で同様のことを実現できるのが利点です。
// Array
const numbers = odd.concat(even)
// Object
const profile = Object.assign(name, age)
Reactではどう使うか
簡単なuserListアプリを作成し、どう使えるか見てみます。
今回のアプリは3つのファイルで構成され、Materialize Cssでスタイリングしています。
import React from 'react';
import InputForm from './components/InputForm';
import UserList from './components/UserList';
class App extends React.Component {
constructor() {
super()
this.state = {
users: []
}
this.addUser = this.addUser.bind(this)
}
addUser(inputUser) {
this.setState({
// ①App.jsにおけるスプレッド構文
users: [...this.state.users, inputUser]
})
}
render() {
return (
<div className="App" >
<h1>Spread</h1>
<div className="row">
<div className="col s6 offset-s3">
<div className="col s6">
<InputForm addUser={this.addUser} />
</div>
<div className="col s6">
<UserList users={this.state.users} />
</div>
</div>
</div>
</div >
);
}
}
export default App;
import React, { useState } from 'react';
const InputForm = (props) => {
const [form, setValues] = useState({
firstName: '',
lastName: ''
});
const changeValue = e => {
setValues({
// ②InputForm.jsxにおけるスプレッド構文
...form,
[e.target.name]: e.target.value
});
};
const addUser = () => {
props.addUser(form)
// formの初期化
setValues({
firstName: '',
lastName: ''
});
}
return (
<div>
<div className="input-field">
<input
id="first_name"
type="text"
className="validate"
name="firstName"
value={form.firstName}
onChange={changeValue}
/>
<label htmlFor="first_name">First Name</label>
</div>
<div className="input-field">
<input
id="last_name"
type="text"
className="validate"
name="lastName"
value={form.lastName}
onChange={changeValue}
/>
<label htmlFor="last_name">Last Name</label>
</div>
<div className="btn" onClick={addUser}>
<span>Add</span>
</div>
</div>
)
}
export default InputForm
import React from 'react';
const UserList = (props) => {
return (
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
{props.users.length !== 0 &&
<tbody>
{props.users.map((user, index) => {
return (
<tr key={index}>
<td>{user.firstName}</td>
<td>{user.lastName}</td>
</tr>
)
})}
</tbody>
}
</table>
)
}
export default UserList
①App.jsにおけるスプレッド構文
addUser(inputUser) {
this.setState({
users: [...this.state.users, inputUser]
})
}
子コンポーネントから送られてきたinputUserとstateで管理している既存のusersをマージするために使用しています。
実際にはDBから再取得しリストを更新するため、
今回のようにユーザーを作成⇨リストを更新する時にスプレッドを使った実装はあまりしないような気がしますが、
一時的に保存する配列...
例えば、グループメンバーの管理画面でユーザーを複数選択して、まとめて追加するといった実装には使えます。
②InputForm.jsxにおけるスプレッド構文
const [form, setValues] = useState({
firstName: '',
lastName: ''
});
const changeValue = e => {
setValues({
...form,
[e.target.name]: e.target.value
});
};
HooksのuseStateを使って複数の値を管理しているため、
formの値を全て展開してマージした後にセットしています。
Hooksで複数の値を用いる時は必須の処理です。
まとめ
今回はlastName,firstNameのみのフォームでしたが、
要素が増えればObject.entries
を使用してうまくまとめることもできます。
参考:React Hooksで複数のFormを扱う
またスプレッド構文自体はHOCなどで頻繁に登場するので、意味を把握しておくことは重要ですね。
宣伝(20240725 追記)
超最近、自分の趣味のメディアを仲間と一緒に作りました!
下記からアクセスしてみてください。
https://www.wai-ware.com/