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

Yuya, htmlReactTypeScriptdom
Back

こんばんは。

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

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

多分、ほとんどの場合は 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 があって使えば楽できるのに存在自体を知らない、というのがいっぱいありそうですね 😅

© Yuya Oiwa