Help us understand the problem. What is going on with this article?

JSのスプレッド演算子でハマったこと

More than 1 year has passed since last update.

はじめに

React, Reduxを学び始めて Spread演算子 を触る機会が増えてきた。自分がはまった点を他の初学者の方のために共有しようと思います。

1. ReactのオブジェクトSpread演算子ではまった


オブジェクトに対してSpread演算子を使用すると
Module build failed: SyntaxError: Unexpected token
とerrorが出て Spread演算子Objectに対してデフォルトで使用出来なかった。

解決方法
標準ではObjectのSpread演算子はサポートしていないので、Babelに追加のpluginを導入することで解決。

https://babeljs.io/docs/en/babel-plugin-transform-object-rest-spread

2. データの渡し方ではまった


以下の画像のように、テキストを打ち込むと配列に新しいデータが追加できるようなコードを作成する

最初に記述していたコード

sample.js
import React from 'react';
import ReactDOM from 'react-dom';

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fruits: ['Apple', 'Banana', 'Orange', 'Cherry', 'Pineapple']
    };
  }
  handleClick = (text) => {
    this.setState({
      ...this.state,
      fruits: [text]
    });
  }
  handleAddText = (e) => {
    e.preventDefault();
    const option = e.target.elements.option.value.trim();
    this.handleClick(option)
    e.target.elements.option.value = '';
  }
  render() {
    console.log(this.state)
    return (
      <div>
        {this.state.fruits.map((fruit, index) => (
        <Child 
          key={index}
          data={fruit} 
        />
        )
        )}
      <form onSubmit={this.handleAddText}>
        <input type="text" name="option" />
        <button>Add Option</button>
      </form>
      </div>
    );
  }
}

const Child = (props) => (
  <div onClick={props.handleClick}>
    {props.data}
  </div>
);

ReactDOM.render(<Parent />, document.getElementById('app'))

上記の記述だと、毎回 valueの配列そのものが更新されてしまい、ObjectのvalueであるArrayに要素の追加が出来なかった。

ObjectのvalueであるArrayに要素の追加のみを記述するには、指定したキー(fruits)の中で更に spread演算子Arrayのみを取り出し、要素をそれから記述する必要があった。

sample.js
import React from 'react';
import ReactDOM from 'react-dom';

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fruits: ['Apple', 'Banana', 'Orange', 'Cherry', 'Pineapple']
    };
  }
  handleClick = (text) => {
    this.setState({
      ...this.state,
      fruits: [
        ...this.state.fruits,
        text
      ]
    });
  }
  handleAddText = (e) => {
    e.preventDefault();
    const option = e.target.elements.option.value.trim();
    this.handleClick(option)
    e.target.elements.option.value = '';
  }
  render() {
    console.log(this.state)
    return (
      <div>
        {this.state.fruits.map((fruit, index) => (
        <Child 
          key={index}
          data={fruit} 
        />
        )
        )}
      <form onSubmit={this.handleAddText}>
        <input type="text" name="option" />
        <button>Add Option</button>
      </form>
      </div>
    );
  }
}

const Child = (props) => (
  <div onClick={props.handleClick}>
    {props.data}
  </div>
);

ReactDOM.render(<Parent />, document.getElementById('app'))

3. 付録 (concatの記述と比較)


上記のコードはconcatを使用して下記のようにも記述出来る。

sample.js
import React from 'react';
import ReactDOM from 'react-dom';

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fruits: ['Apple', 'Banana', 'Orange', 'Cherry', 'Pineapple']
    };
  }
  handleClick = (text) => {
    this.setState((prevState) => ({
      fruits: prevState.fruits.concat(text)
    }));
  }
  handleAddText = (e) => {
    e.preventDefault();
    const option = e.target.elements.option.value.trim();
    this.handleClick(option)
    e.target.elements.option.value = '';
  }
  render() {
    console.log(this.state)
    return (
      <div>
        {this.state.fruits.map((fruit, index) => (
        <Child 
          key={index}
          data={fruit} 
        />
        )
        )}
      <form onSubmit={this.handleAddText}>
        <input type="text" name="option" />
        <button>Add Option</button>
      </form>
      </div>
    );
  }
}

const Child = (props) => (
  <div onClick={props.handleClick}>
    {props.data}
  </div>
);

ReactDOM.render(<Parent />, document.getElementById('app'))
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした