ReactのuseStateで配列を扱う

React_icon React
この記事は約9分で読めます。

この記事は以下の方を対象に書いています。

  • useStateで配列を扱いたい
  • 配列をどのように扱うかのサンプルコードを見たい

はじめに

今回は、useStateを使った中級編?として、配列を扱い、

どのように状態の更新をするのかを見ていきます。

useStateの基本的な使い方を知りたい方は、以下の記事で解説していますので、ぜひご参考に!

複数の日付を格納した配列を管理

まずは、以下のコードを書いて、動作を確かめてみます。

onChangeで呼ばれる関数内でアラートを使用して配列の中身を

確認すると分かりますが、画面上では値の変更をしても

配列の中身は変化していないことが分かります。

import React, { useRef, useState } from 'react';

function App(): JSX.Element {
  // サンプルデータ
  const data = ['2023-09-01', '2023-09-02', '2023-09-03'];
  // string型の配列を準備してuseStateの初期値として設定
  const [dates, setDates] = useState<string[]>(data);

  // 変更があった場合に呼び出される関数
  const handleChange = (e: any, index: number) => {
    // --------あとでここを変更します------------
  };

  return (
    <>
      <div style={{ margin: '30px' }}>
        {/* datesの要素分ループして、inputタグを作る */}
        {dates.map((item, index) => {
          return <input style={{ marginLeft: '10px' }} type="date" defaultValue={item} onChange={(e: any) => handleChange(e, index)} />
        })}
      </div>
      {/* 配列の中身を確認 */}
      <div style={{ margin: '50px' }}>{dates.join(' , ')}</div>
    </>
  );
}

export default App;
react_useState_description1
実行結果

これで準備は出来ましたので、ここから配列の操作をしてみます。

この時点では、値を変更してもuseState内のdatesの中身は変化していません。

そのため、onChangeで呼ばれる関数内で配列を更新しなければなりません。

import React, { useRef, useState } from 'react';

function App(): JSX.Element {
  // サンプルデータ
  const data = ['2023-09-01', '2023-09-02', '2023-09-03'];
  // string型の配列を準備してuseStateの初期値として設定
  const [dates, setDates] = useState<string[]>(data);

  // 変更があった場合に呼び出される関数
  const handleChange = (e: any, index: number) => {
    // 現在のdatesをコピー(これがないと再レンダリングされない:重要)
    const updateDates = [...dates];
    // 変更したinputの内容をコピーした配列に上書き
    updateDates[index] = e.target.value;
    // 上書きした配列でuseStateの更新
    setDates(updateDates);
  };

  return (
    <>
      <div style={{ margin: '30px' }}>
        {/* datesの要素分ループして、inputタグを作る */}
        {dates.map((item, index) => {
          return <input style={{ marginLeft: '10px' }} type="date" defaultValue={item} onChange={(e: any) => handleChange(e, index)} />
        })}
      </div>
      {/* 配列の中身を確認 */}
      <div style={{ margin: '50px' }}>{dates.join(' , ')}</div>
    </>
  );
}

export default App;
react_useState_description2
実行結果

これで、値の変更をしたときも配列の中身が変わることを確認できました!!

配列の後ろに追加したい場合

上で紹介した方法ではなく、日付を変更するたびに要素を追加したい場合もあると思います。

その場合は、スプレッド構文を使うと簡単に記述できます。

import React, { useRef, useState } from 'react';

function App(): JSX.Element {
  // サンプルデータ
  const data = ['2023-09-01', '2023-09-02', '2023-09-03'];
  // string型の配列を準備してuseStateの初期値として設定
  const [dates, setDates] = useState<string[]>(data);

  // 変更があった場合に呼び出される関数
  const handleChange = (e: any) => {
    // スプレッド構文を使用して、配列の最後に要素を追加
    setDates([...dates, e.target.value])
  };

  return (
    <>
      <div style={{ margin: '30px' }}>
        {/* 初期値は最後の要素、変更があった場合はhandleChange関数を呼び出す */}
        <input type="date" defaultValue={dates[dates.length - 1]} onChange={(e: any) => handleChange(e)} />
      </div>
      {/* 配列の要素を表示 */}
      <div style={{ margin: '50px' }}>{dates.join(' , ')}</div>
    </>
  );
}

export default App;
react_useState_description3
実行結果

備考

今回の解説で書いたコードの中にもう少し説明したいことが、

いくつかありましたので、補足します。

スプレッド構文

スプレッド構文は、「…」のことです。

勉強し始めた時は、書き間違いかな?と思っちゃうやつです。

でも、これがすごく便利なんです。

これは言葉では分かりづらいので、サンプルコードを見てください。

const array = [1, 2, 3]
const tempArray = [4, 5]

console.log([...array, ...tempArray]) // [ 1, 2, 3, 4, 5 ]
console.log([-1, 0, ...array])        // [ -1, 0, 1, 2, 3 ]

これくらいなら、そんなに便利だとは感じないですよね?(便利ではあるけど。。。)

安心してください、スプレッド構文はこんなもんじゃありまっせん。

const obj = {'name': 'ito', age: '24'}

console.log({...obj})
// { name: 'ito', age: '24' }

console.log({...obj, 'age': '32'})
// { name: 'ito', age: '32' }

console.log({...obj, 'foot size': '26cm'})
//{ name: 'ito', age: '24', 'foot size': '26cm' }

このように、オブジェクトのプロパティを変更したり、新しく追加したりできます。

スプレッド構文に慣れると、配列の操作も自由自在です。

joinメソッド

次は、joinメソッドについてです。

このメソッドも非常に便利で、配列の中の値を結合してくれます。

const array = ['hello', 'Tom']
console.log(array.join(', ')) // hello, Tom

const array2 = [1, 3]
console.log(array2.join(2)) // 123

console.log(array.join(array2)) // hello1,3Tom

このように、値の結合がシンプルになります。

数字でも問題ありませんし、配列同士でも問題ありません。

ただし、型には注意しておかないと、後々バグになる可能性もあるので、

型には注意しましょう。

また、配列の操作系メソッドは以下の記事でも紹介していますので、

気になる方は、ご覧ください。

最後に

ここまで読んでいただきありがとうございます。

今回はuseStateで配列データを扱う方法について解説しました。

配列の操作って面倒ですよね。。。

でも思い通りに動かせたときは、すごく嬉しいし、

開発できる機能も増えるのでどんどん使ってみてください!

いっぱいサンプルコードを改造して練習するのが良いと思います!

コメント

タイトルとURLをコピーしました