選択肢を数値で扱いたくてハマったのでメモ
環境
- react-hook-form 7.9.0
- @material-ui/core 4.11.3
結論
const OneOrTwo = ({ control }: { control: Control<{ oneOrTwo : number }> }) => (
<Controller
name="oneOrTwo"
control={control}
render={({ field }) => (
<RadioGroup
name={field.name}
onChange={(e) => {
const value = parseInt(e.target.value)
if (!isNaN(value)) {
field.onChange(value)
}
}}
value={field.value === undefined ? '' : field.value}
>
<FormControlLabel
value={1}
control={<Radio />}
label="1"
/>
<FormControlLabel
value={2}
control={<Radio />}
label="2"
/>
</RadioGroup>
)}
/>
)
作業メモ
選択してもチェックされない??
field
をそのまま展開すると、ラジオボタンを選択したときにuseFormの内部では値が変化しているが、チェックが付かなかった。
FormControlLabel.value
を文字列にしたらチェックが付くが、useFormの内部の値が文字列になっている。
before
render={({ field }) => (<RadioGroup {...field}><FormControlLabel value={1} ...
after
render={({ field }) => (<RadioGroup {...field}><FormControlLabel value="1" ...
Material-UIのワーニングが出る
A component is changing the uncontrolled value state of RadioGroup to be controlled.
と怒られる。
formとして未選択の状態を存在させたい場合は、RadioGroup.value
の値を指定することで回避できる。
before
render={({ field }) => (<RadioGroup {...field}> ...
after
render={({ field }) => (<RadioGroup {...field} value={field.value === undefined ? '' : field.value}> ...
useFormの内部で値が文字列として保持されている
選択してもチェックされない??
でvalue="1"
としたので、当然こうなる。
v6ではvalueAsNumber
を指定すれば良かったが、v7ではControllerでは使えないので、onChange
を上書きする。(結論
を参考)
参考
v7ではControllerではvalueAsNumber使えない
https://react-hook-form.com/advanced-usage#TransformandParse