- 投稿日:2020-01-04T16:52:39+09:00
Reactにおけるスプレッド構文の使い所
スプレッド構文を使うようになってからコードの可読性が上がったように感じたので、
どのようなところで使っているのかまとめます。スプレッド構文とは
example.js// 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()
を使い実現していたことを短い記述で同様のことを実現できるのが利点です。example.js// Array const numbers = odd.concat(even) // Object const profile = Object.assign(name, age)Reactではどう使うか
簡単なuserListアプリを作成し、どう使えるか見てみます。
コードは、ここ(GitHubに飛びます)今回のアプリは3つのファイルで構成され、Materialize Cssでスタイリングしています。
App.jsimport 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;InputForm.jsximport 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 InputFormUserList.jsximport 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におけるスプレッド構文
App.jsxaddUser(inputUser) { this.setState({ users: [...this.state.users, inputUser] }) }子コンポーネントから送られてきたinputUserとstateで管理している既存のusersをマージするために使用しています。
実際にはDBから再取得しリストを更新するため、
今回のようにユーザーを作成⇨リストを更新する時にスプレッドを使った実装はあまりしないような気がしますが、
一時的に保存する配列...
例えば、グループメンバーの管理画面でユーザーを複数選択して、まとめて追加するといった実装には使えます。②InputForm.jsxにおけるスプレッド構文
InputForm.jsxconst [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などで頻繁に登場するので、意味を把握しておくことは重要ですね。