[英]onKeyDown and onChange with React and TypeScript
我正在尝试使用 TypeScript 将onChange
和onKeyDown
分配给 Input 组件,这已经失控了。
我有这个Input
组件:
import React, { ChangeEvent, KeyboardEvent } from 'react'
import { InputStyle } from './Input-style'
type InputProps = {
name: string
value: string | number
type?: string
placeholder?: string
onBlur?: () => void
onKeyDown?: (e: KeyboardEvent) => void
onChange?: (e: ChangeEvent<HTMLInputElement>) => void
}
export const Input = (props: InputProps) => (
<InputStyle
type={props.type ? props.type : 'text'}
name={props.name}
id={props.name}
placeholder={props.placeholder}
value={props.value}
onKeyDown={props.onKeyDown}
onChange={props.onChange}
onBlur={props.onBlur}
/>
)
然后我使用该组件做两件事,验证输入的按键是一个数字,然后添加值,似乎很容易的任务就是给我各种关于类型的 TypeScript 错误
import React, { KeyboardEvent, ChangeEvent } from 'react'
export const renderInput = () => {
const [rate, setRate] = useState<number>(0)
// I want to add the value only if is a number and between 0-1 no letters
const addRate = (e: KeyboardEvent | ChangeEvent) => {
const element = e.target as HTMLInputElement
const value = element.value
if ('key' in e) {
const reg = /[0-9]/
// If is not a letter
if (reg.test(e.key)) {
// Add the value but here now it breaks
setRate(isNaN(value) || value > 1 ? 0 : value)
}
}
}
return (
<Input
type='number'
name='Conversion Rate'
value={rate === 0 ? '' : rate}
placeholder='Percentage Decimal number'
onKeyDown={addRate}
onChange={addRate}
/>
)
}
但此时 TypeScript 错误与
'string | 类型的参数 0' 不可分配给“SetStateAction”类型的参数
在尝试检查它是否有效之前,我真的很困惑。
错误的原因是因为 HTML 中的字段总是返回文本值,即使它们是type="number"
字段。 为了在 state 中设置值,您需要首先将字符串解析为数字,否则您将收到您看到的类型错误,因为您的 state 被键入为数字。
<Input
type="number"
value={rate}
onInput={e => setRate(Number(e.target.value))}
/>
数字字段将只允许有效的数字字符(包括小数和大指数的e
)。 所以你不需要在你的代码中做所有的验证; Number()
可以解析 number 字段允许的任何内容。
最后,始终使用onInput
来捕获输入,因为这也会捕获诸如拖放、剪切和粘贴、数字字段上的向上/向下箭头等内容。
编辑:您说您的评论您不希望 go 的值高于 1。您可以在数字字段上设置最大值和最小值。
<Input type="number" min="0" max="1" />
如果您真的需要在代码中限制值,以下将确保即使高于 1 的值也会被限制回 1。
<Input
onInput={e => setRate(Math.max(1, Number(e.target.value)))}
/>
我猜element.value
是字符串类型。
您可以使用parseInt(element.value)
或+element.value
将其解析为数字
那将是: const value = +element.value
onKeyDown 调度值作为字符,因此 Typescript 冲突类型。
您可以在 parseInt(value, 10) 中进行转换。
您应该注意,字段类型 number 已经只接受数字和指数的“e”。
没有一个答案对我有用,它们可能在原则上听起来是正确的,但根据我的例子,它只是相互冲突。 我正前往 TypeScript 地狱,所以我通过使用常规文本输入和一些正则表达式摆脱了它:
const addRate = (val: string) => {
// If it's a number and is higher than 1 exit
if (!isNaN(parseInt(val)) && parseFloat(val) > 1) {
return
}
// Regex to allow only decimal mumbers
const reg = /^\d*(?:[.]\d*)?$/
if (reg.test(val)) setRate(val)
}
<Input
name='Conversion Rate'
value={rate}
placeholder='Decimal number - Optional'
onChange={e => addRate(e.target.value)}
/>
没有输入类型号,没有 keydown 只是正则表达式
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.