はじめに
このシリーズは、Reactの公式ページなどから特に重要と感じたトピックを選び出し、何度でも読み返せるよう簡潔にまとめたものです。
進捗管理には「いいね」か「ブックマーク」がお勧め
さらに僕のモチベーションアップになります! よろしくお願いいたします!
よろしくお願いいたします!
state配列の更新方法
配列の更新を行いたい場合は、新しい配列を作成し更新を行います。
0.なぜ新しい配列を作成するのか?
1.末尾追加
2.指定の要素削除
3.指定の要素置換
4.任意の位置への挿入
5.配列自体の変更(Sort,Reverce)
0.なぜ新しい配列を作成するのか?
例えば下記の場合、stateでエラーも発生せず無事に更新できているように見えます。
const [artists, setArtists] = useState([]);
...
artists.push({
  id: nextId++,
  name: name,
}
ただし、この場合だと更新用関数を使用していないため、再レンダリングが発生しません。Reactの書き方としてはルール違反していることになります。
stateの配列にsetArtistsを経由して追加したいだけの場合、どうすればいいでしょうか?
そこで配列のコピー(再定義)が必要になります。
const [artists, setArtists] = useState([]);
...
setArtists( 
  [
    ...artists, //配列をスプレット構文でシャローコピーします。
    { id: nextId++, name: name } //新しい情報を定義
  ]
);
1.末尾追加
スプレット構文を使用することで新しい配列の作成を行います。
setArtists([
  ...artists,
  { id: nextId++, name: name }
])
2.指定の要素削除
filterを使用し、指定した要素以外を抽出し配列の作成を行います。
setArtists(
 artists.filter(artist =>
   artist.id !== targetId
 )
)
3.指定の要素置換
mapを使用します。
setArtists(artists.map(artist => {
  if (artist.id === targetId) {
    // 対象のnameだけ変更
    return {...artist,name: 'change'}
  } else {
    // それ以外はそのまま
    return artist;
  }
}))
4.任意の位置への挿入
sliceを使います。
sliceは半開区間で処理対象が決定します。
例えば(0,1)で指定した場合は0以上1未満となり、0が処理対象になります。
const insertAt = 1;
setArtists([
  // インデックスが0の配列をコピー
  ...artists.slice(0, insertAt),
  // 新しい値の挿入
  { id: nextId++, name: name },
  // インデックスが1以上の配列をコピー
  ...artists.slice(insertAt)
])
5.配列自体の変更(Sort,Reverce)
配列を逆順にしたり、ソートしたりするのはmapやfilter等ではできません。
スプレット構文で配列をコピーしてから関数を使用し新しい配列をセットしましょう。
// Sort(昇順)
const sortedList = [...list].sort((a, b) => a - b)
setList(sortedList)
// Reverce
const reverseList = [...list]
reverseList.reverse()
setList(nextList)
参考サイト
より詳しく学びたい方はこちら