LoginSignup
0
0

More than 1 year has passed since last update.

Reactのフォームの返り値と渡す値、型バラバラ問題(数値)

Last updated at Posted at 2021-05-18

課題

Reactでフォームを実装したい。
React Hooksでcountを管理している。
ここで、素直にinputに値を渡して、変更があればinputの返り値で価格を変更してみる。

index.tsx
import { useState } from 'react'

const Index = () => {
    const [count, setCount] = useState(0)
    return <input 
        type='number' 
        value={count} 
        onChange={e=>setCount(e.target.value)}
    />
}
export default Index

今回は、初期値0から100に変更したとする
初期値は、number型の0
変更があると、string型の100となる。
これでは困る。
別のcount=500があったとしてその合計を求めると、'100500'となってしまう。

解決法

React hooksやreduxなどデータストアの型は変えない。
→表示するときに適した型に変換する
→変更があるときは、データストアと同じ型に変換する
の2つを守れば大体解決する

index.tsx
import { useState } from 'react'

const Index = () => {
    const [price, setPrice] = useState(0)
    return <input 
        type='number' 
        value={price==0 ? '' : String(price)} 
        onChange={e=>setPrice(Number(e.target.value))}
    />
}
export default Index


// or

import { useState } from 'react'

const Index = () => {
    const [price, setPrice] = useState(0)
    return <input 
        type='number' 
        value={isNaN(price) ? '' : String(price)} 
        onChange={e=>setPrice(e.target.valueAsNumber)}
    />
}
export default Index

このようにこのように型を合わせてあげれば良い。
少し余計な処理があるが、これはinputを全部消してもデータストアは0にしかならず、0が必ず最後に表示されてしまうため0を消す処理を書いている。

個人的に、NaNを用いた方が見やすいと考えている。
データを送信するときに、入力のバリデーションでcount==0isNaN(count)だと後者の方が0を許容できるのと直感的だから。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0