【React + Typescript】フォーム input の値を取得する(+ 取得関数を使い回す)

  • React
  • Typescript

React でフォームの値を取得する方法です。また input の値を取得する時に使い回す方法も紹介します。今回は「Controlled Input(制御された input)」という、データ側から input の値を制御する方法です。

React で onChange でフォームの値を取得

useStateを使用する例です。

import { useState } from 'react';

// インターフェース
const interface IData {
  userName: string
  mailAddress: string
}
// 初期データ
const initialData: IData = {
  userName: '',
  mailAddress: '',
}
// データ
const [data, setData] = useState<IData>(initialData);

// onChange で取得
const onChangeUserName = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    setData({ ...data, userName: value });
}
const onChangeMailAddress = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    setData({ ...data, mailAddress: value });
}

return (
  <div>
    <input name="userName" value={data.userName} onChange={onChangeUserName} />
    <input name="mailAddress" value={data.mailAddress} onChange={onChangeMailAddress} />
  </div>
)
  1. フォーム初期値オブジェクトを定義して、state に代入。
  2. それぞれの input の onChange イベント時に、setData() で値をセットする

ということをやっています。

setData() のスプレッド構文は何なの?

setData()の中では{ ...data, userName: value }のようなスプレッド構文で data を挿入しています。

{...data}で展開すると、単に data の中身が展開されるだけなので同じ内容のオブジェクトがセットされてしまいますが、中身を全てセットした後で指定した値は上書きされます。

data の中身は常に { userName, mailAddress } が入ってなくてはならないので、

setData({ userName: value })

のようにしてしまうと、data の中身は userName のみになってしまいます。なので、一旦...dataで data の中身を展開してから、上書きしたいものを指定する方法を使っています。

例 スプレッド構文で name だけ上書きする

const data = {
  name: '太郎',
  pass: 'パスワード'
}

{...data, name: 'ジャック'}
<- { name: 'ジャック', pass: 'パスワード' } 

onChange で input の中身を取得する関数を使い回せるようにする

今回の例では、onChange の時に使っている関数が userName も mailAddress もほとんど同じです。唯一、setData()でセットするときのキーが違うだけとなっています。

const onChangeMailAddress = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    setData({ ...data, mailAddress: value }); // ここのキーだけ違う!
}

これで input が増えると、また似たような関数を定義することになります。これは面倒なので、もっと汎用的に使えるようにします。

input ではたいてい name 属性を指定すると思いますが、今回はこの name 属性の値と data オブジェクトのキー名が同じなので、input の name をキーとして値をセットできるようにしてみます。

onChange で input の値を取得する時に使い回せる関数

const handleChangeInput = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    const name = event.target.name;
    setData({ ...data, [name]: value });
}

...

return (
  <div>
    <input name="userName" value={data.username} onChange={handleChangeInput}>
    <input name="mailAddress" value={data.username} onChange={handleChangeInput}>
  </div>
)

input の name 値を動的に取得できるようにすることで、現在入力されている input をsetData()でセットし続けることができます。