Reactを初学者に教える機会があり、その時によくハマりがちなのが「stateに配列でデータを持たせた時に、正しく更新できていない」ケースです。 エラーで落ちるわけでなく、renderがかからない等の気づきにくい不具合なので、原因特定がしにくいですが大体はこの記事の例に収まると思います。
react
の初級者向けstate
に配列でデータを保持しているstate
に配列としてデータを持っていて更新する場合、取得した配列を破壊的に変更してはいけません。
具体的には要素追加のpush
や要素削除のsplice
などがあたります。
// state定義
this.state = {
list : []
}
// ...略
let { list } = this.state;
// 要素の追加
list.push("Test"); // -> NG
// 要素の削除
list.splice(0,1); // -> NG
詳しく解説すると、let { list } = this.state
で取得したlist
が参照渡しであるため、
内容を破壊的に変更するとsetState()
を待たずして値を書き換えてしまうためです。
// 実質下記の記法と同じ
// setState以外の方法でstateを書き換えてもrenderが走りません
// 要素の追加
this.state.list.push("Test"); // -> NG
// 要素の削除
this.state.list.splice(0,1); // -> NG
スプレッド演算子...
やArray.from()
を使って、別インスタンスとして配列を持たせてから変更しましょう。
// スプレッド演算子で配列を展開し、同じ値を持った別配列として再定義
let copyList = [...this.state.list];
// Array.from()でもOKです
// copyList = Array.from(this.state.list);
copyList.push("Test"); // -> OK
copyList.splice(0,1); // -> OK
this.setState({
list : copyList,
})
今回はreact
初学者が陥りがちなstate
内の配列の扱い方についてご紹介しました。
ぱっと見は動作しますが、render
が正しいタイミングでかからない等の不具合の原因となるので、しっかりと頭に入れておきましょう。