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 的输入

React Hook | 必 学 的 9 个 钩子

组件挂载上的 React hook Redirect

如何测试使用自定义 TypeScript React Hook 的组件?

如何在 React Native 应用程序中使用 React hook useEffect 为每 5 秒渲染设置间隔?

如何测试使用自定义TypeScript React Hook的组件?