29
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Reactにおけるスプレッド構文の使い所

Last updated at Posted at 2020-01-04

スプレッド構文を使うようになってからコードの可読性が上がったように感じたので、
どのようなところで使っているのかまとめます。

スプレッド構文とは

配列 や オブジェクトをその場で展開する構文

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アプリを作成し、どう使えるか見てみます。

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

宣伝(20240725 追記)

超最近、自分の趣味のメディアを仲間と一緒に作りました!
下記からアクセスしてみてください。
https://www.wai-ware.com/

29
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?