はじめに
React, Reduxを学び始めて Spread演算子
を触る機会が増えてきた。自分がはまった点を他の初学者の方のために共有しようと思います。
1. ReactのオブジェクトSpread演算子ではまった
オブジェクトに対してSpread演算子を使用すると
Module build failed: SyntaxError: Unexpected token
とerrorが出て Spread演算子
がObject
に対してデフォルトで使用出来なかった。
解決方法
標準ではObject
のSpread演算子はサポートしていないので、Babelに追加のpluginを導入することで解決。
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'))