20200104のReactに関する記事は1件です。

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に飛びます)

スクリーンショット 2020-01-04 12.55.02.png

今回のアプリは3つのファイルで構成され、Materialize Cssでスタイリングしています。

App.js
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;
InputForm.jsx
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
UserList.jsx
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におけるスプレッド構文

App.jsx
  addUser(inputUser) {
    this.setState({
      users: [...this.state.users, inputUser]
    })
  }

子コンポーネントから送られてきたinputUserとstateで管理している既存のusersをマージするために使用しています。
実際にはDBから再取得しリストを更新するため、
今回のようにユーザーを作成⇨リストを更新する時にスプレッドを使った実装はあまりしないような気がしますが、
一時的に保存する配列...
例えば、グループメンバーの管理画面でユーザーを複数選択して、まとめて追加するといった実装には使えます。

②InputForm.jsxにおけるスプレッド構文

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などで頻繁に登場するので、意味を把握しておくことは重要ですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む