React 钩子表单:如何在 React Hook 表单版本 7.0 上使用 onChange
Posted
技术标签:
【中文标题】React 钩子表单:如何在 React Hook 表单版本 7.0 上使用 onChange【英文标题】:React hook form: How to can I use onChange on React Hook Form Version 7.0 【发布时间】:2021-06-30 07:38:16 【问题描述】:以前我是这样写的:
<input className="form-control" name="productImage" type='file' onChange=handleImageUpload ref=register( required: true ) />
更新后我要这样写:
<input className="form-control" type="file" ...register('productImage', required: true ) />
如何在 React Hook Form 的更新版本上使用onChange=handleImageUpload
?
这里是迁移docs
请原谅我在提问方式上的错误。我对这些东西很陌生。 谢谢。
【问题讨论】:
您不必对 react-hook-form v7.0.0 中的onChange
属性进行任何更改。
如何像我展示的第一行代码一样使用 onChange=handleImageUpload) 调用 handleImageUpload()?
onChange=handleImageUpload)
应该可以工作。如果您遇到任何问题,可以分享CodeSandbox 吗?
这是我的CodeSandbox,而 onChange=handleImageUpload 在我的代码中不起作用。
上传文件时会调用handleImageUpload
函数。
【参考方案1】:
您只需将onChange
道具移动到...register(...)
之后
const productImageField = register("productImage", required: true );
return (
<input
className="form-control"
type="file"
...productImageField
onChange=(e) =>
productImageField.onChange(e);
handleImageUpload(e);
/>
)
(2021 年 12 月 3 日)编辑:这种方法不再正确,因为 react-hook-form v7.16.0's changes,请参阅 @Bill 的回答。
【讨论】:
@DiamondDrake 你确定这会覆盖 onChange 函数吗?上面的示例首先覆盖了 onChange 函数,然后在我们覆盖的 onChange 函数productImageField.onChange(e);
中调用它。那么,我没有到达这里的原因是什么?
@Tanckom 自从@DiamondDrake 发表评论后,我已经更新了我的回复
@Joris,最好在您的回答中提及这一点,因为新观众可能会感到困惑,这不是正确的方法:-)
@Tanckmon 是正确的,此解决方案将覆盖从 ...register('name')
传播的 onChange
处理程序,并可能导致错误。 @Bill 的答案似乎是正确的。【参考方案2】:
https://github.com/react-hook-form/react-hook-form/releases/tag/v7.16.0
V7.16.0 为自定义 onChange
引入了这个新 API。
<input
type="text"
...register('test',
onChange: (e) => ,
onBlur: (e) => ,
)
/>
【讨论】:
这是正确的答案,因为 @Joris 的解决方案将覆盖从返回onChange, onBlur, name, ref
的 ...register('name')
传播的更改处理程序,这可能会导致错误。【参考方案3】:
在register
文档https://react-hook-form.com/api/useform/register 中,样本存在于Custom onChange, onBlur
部分:
// onChange got overwrite by register method
<input onChange=handleChange ...register('test') />
// register's onChange got overwrite by register method
<input ...register('test') onChange=handleChange/>
const firstName = register('firstName', required: true )
<input
onChange=(e) =>
firstName.onChange(e); // method from hook form register
handleChange(e); // your method
onBlur=firstName.onBlur
ref=firstName.ref
/>
所以对于你的情况:
const productImageRegister = register("productImage", required: true)
<input className="form-control"
type="file"
...productImageRegister
onChange=e =>
productImageRegister.onChange(e);
handleImageUpload(e);
/>
【讨论】:
【参考方案4】:对我来说,装饰解决方案有效
const fieldRegister = register("productImage", required: true)
const origOnChange = fieldRegister.onChange
fieldRegister.onChange = (e) =>
const res = origOnChange(e)
const value = e.target.value
// do something with value
return res
字段声明使用
<input ...fieldRegister/>
【讨论】:
有点冗长,但这对于那些运行早于v7.16.0的人来说非常有用【参考方案5】:我最近在迁移到 V7 时遇到了类似的问题。如果它可以帮助任何人。
处理表单的父组件将注册函数向下传递给包装器,包装器将其再次向下传递到需要在更改时去抖动的输入。
我调用了寄存器 formLibraryRef
以防我以后想使用不同的库,但总的来说我必须做类似的事情:
const onChange, ...rest = formLibraryRef(inputName);
将 onChange 传递给函数,该函数本身传递给输入的原生 onChange 事件:
const handleDebouncedChange: (event: React.ChangeEvent<htmlInputElement>) => void = (
event: ChangeEvent<HTMLInputElement>,
) =>
onChange(event);
if (preCallback)
preCallback();
debounceInput(event);
;
然后将其余部分传递给输入:
<input
aria-label=inputName
name=inputName
data-testid=dataTestId
className=`form-control ...$classNames`
id=inputId
onChange=handleDebouncedChange
onFocus=onFocus
placeholder=I18n.t(placeholder)
...rest
/>
此处文档中的 register
部分:https://react-hook-form.com/migrate-v6-to-v7/ 提供了有关如何获取 onChange 的更多信息,并显示了 Missing ref
的示例。
【讨论】:
以上是关于React 钩子表单:如何在 React Hook 表单版本 7.0 上使用 onChange的主要内容,如果未能解决你的问题,请参考以下文章
React 钩子表单不适用于来自 reactstrap 的输入
如何测试使用自定义 TypeScript React Hook 的组件?