簡易的なフォームなら非制御コンポーネント使って楽しよ

公開:2021/01/13
更新:2021/01/13
2 min読了の目安(約2100字TECH技術記事

こんばんは。

今日は、ちょっとしたフォームの(あまり知られてない?)小技を紹介します。

まず、フォームを作る際、みなさんどのようにフォームのステートを管理していますか?

多分、ほとんどの場合は useState などでコンポーネントで状態管理していると思います。

こんな風に:

function Form() {
  const [form, update] = React.useState({
    name: '',
    email: ''
  })
  
  const save = e => {
     e.preventDefault();
     fetch('/some-api', {
        body: JSON.stringify(form)
     })
  }
  
  return (
    <form onSubmit={save}>
      <label>
        Name
        <input type="text" name="name" value={form.name} onChange={e => update({ ...form, name: e.target.value })} />
      </label>
      <label>
        Email
        <input type="text" name="email" value={form.email} onChange={e => update({ ...form, email: e.target.value })}/>
      </label>
      <button>Save</button>
    </form>
  );
}

ボイラープレート多めですが、ほぼこのようなコード(ローカルステートにそれぞれの値を保存)なので、普通に見えると思います。

ですが、FormData Web API をみなさんご存知ですか?

特殊なフォーム用のAPIで、こいつを活用すれば劇的にコード量は減ります。例えば、上のコードを FormData を使うようにすると、、、

function Form() {
  const save = (e) => {
    e.preventDefault();
    let formData = new FormData(e.target);
    const data = Object.fromEntries(formData); // {name: "test", email: "test@gmail.com"}
    
    // あとは data をサーバーに送れるようにゴニョゴニョするだけ
  };
  return (
    <form onSubmit={save}>
      <label>
        Name
        <input type="text" name="name" />
      </label>
      <label>
        Email
        <input type="text" name="email" />
      </label>
      <button>Save</button>
    </form>
  );
}

おまけ:query string を作るのも、FormData と URLSearchParams を活用すればパッケージとか使わずとも簡単にできます。

function Form() {
  const save = (e) => {
    e.preventDefault();
    let formData = new FormData(e.target);
    const parameters = new URLSearchParams(formData);
    const paramsToString = parameters.toString(); // name=test&email=test@gmail.com 
  };
  return (
    <form onSubmit={save}>
      <label>
        Name
        <input type="text" name="name" />
      </label>
      <label>
        Email
        <input type="text" name="email" />
      </label>
      <button>Save</button>
    </form>
  );
}

このように、色んな Web API があって使えば楽できるのに存在自体を知らない、というのがいっぱいありそうですね😅