以下の内容はhttps://let.blog.jp/tag/formより取得しました。


フォームを管理するツールを使うより直接コンポーネントを使うほうが楽な場合
選択肢から選ぶ入力箇所が A, B の 2 つ
B の選択肢は A の選択に依存

const Component = () => {
const [a, setA] = useState("")
const [b, setB] = useState("")

const b_options = {
"": ["", "1"],
"foo": ["", "foo1"],
"bar": ["", "bar1", "bar2"],
}[a]

return (
<div>
<Select
options={["", "foo", "bar"]}
value={a}
onChange={selected => setA(selected)}
/>
<Select
options={b_options}
value={b}
onChange={selected => setB(selected)}
/>
</div>
)
}

A で foo を選ぶと B の選択肢は未入力か foo1 のどちらか
foo1 が選ばれてるときに A を bar に変更したら?

A が bar のときの B の選択肢に foo1 はないので B をリセットする必要がある
b_options が決まったあとに修正済みの B の値を作ってそれを props で渡す

const Component = () => {
const [a, setA] = useState("")
const [b, setB] = useState("")

const b_options = {
"": ["", "1"],
"foo": ["", "foo1"],
"bar": ["", "bar1", "bar2"],
}[a]

const fixed_b = b_options.includes(b) ? b : ""

return (
<div>
<Select
options={["", "foo", "bar"]}
value={a}
onChange={selected => setA(selected)}
/>
<Select
options={b_options}
value={fixed_b}
onChange={selected => setB(selected)}
/>
</div>
)
}

修正済みの B の値は state には入ってないけど save などの関数で参照したい場合に fixed_b を見ればいい

Controlled なコンポーネントで直接 props を渡せる場合はこれでいいけど ライブラリなどでフォームの値を管理してると 直接 props を渡して今の値を指定できないこともある
フォームのオブジェクトの setValue などを呼び出して B の値を変更することになる
更新処理なので副作用になって useEffect の中で呼び出す
これだけのために useEffect はあまりしたくない

A が変わった時点で B の選択肢と B の値が変わることも確定なので A の変更時のイベントで B の選択肢と B の値も更新?

const onChange = selected => {
setA(selected)
const b_options = {...}[selected]
setBOptions(b_options)
setB(b_options.includes(b) ? b : "")
}

B の選択肢は API で取得する可能性もある
onChange で API 呼び出しで選択肢の更新までするのはあまりやりたいものじゃない

変にフォームを管理するよりシンプルに Input 系コンポーネントを扱うほうが楽なことも多い気がしてきた
フォームの送信ボタン連打問題
onclick みたいなイベントにするから起きるのであって
Promise にすれば 1 回限りのはず

document.querySelector("#submit").addEventListener("click", () => {
form.resolve()
})

form.then(async () => {
const response = await fetch("/path/to/api", {
method: "POST",
headers: { "Content-Type": "applicatin/json" },
body: JSON.stringify(values),
})

// response に応じてなにかの処理
})
input のデータを変数で持つときの変数の型
lit-html や React などを使うときの input の変更を監視して変数と同期させる場合の話

変更イベント時に input などから取得した値はすべて文字列型
最終的に数値や日付型などにしたいので変数側は数値など本来の型で保存したい
だけど 毎回変換して代入は面倒
一応 input に valueAsNumber や valueAsDate もあるけど 空文字列の扱いなど思い通りにならなくて多少手を加えるので 結局ただの value で受け取ってる
それに render 時の input の value には文字列で指定が必要
数値ならそのままでもいいけど 日付は指定のフォーマットの文字列化が必須
処理が増える上に 不可逆な変換になるケースもある

いろいろ試したけどやっぱり フォームパーツと対応付ける部分は文字列として保持するのがベストな気がする
最初に取得してきたときに文字列化して 最後に POST するときなどに数値型等に変換

const values = {
form: {
num: "",
date: "",
},
...
}

const init = (current) => {
values.form.num = String(current.num)
values.form.date = lib.dateFormat("yyyy-MM-dd", current.date)
}

const update = ({ form }) => {
render(
html`
<input type="number" value=${form.num} oninput=${...} />
<input type="date" value=${form.date} oninput=${...} />
`,
document.body
)
}

const post = () => {
const num = ~~values.form.num
const date = new Date(values.form.date)
const body = JSON.stringify({ num, date })

// fetch(...)
}

update(values)
フォーム作るのに便利かも
https://nosir.github.io/cleave.js/

クレカ番号でどの会社か表示してくれたり 電話番号でスペース開けてくれたり
日本指定したら固定電話と携帯でスペースの位置が変わったりとすごく親切

日付や時刻もあるし ユーザがフォーマットの指定もできる
法則性のあるテキストを入力してもらうときに入れとく便利かも



以上の内容はhttps://let.blog.jp/tag/formより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14