如何在 class 组件中使用 react-hook-form?

How to use react-hook-form inside class Component?

我使用以下代码创建一个带有表单验证的登录页面:

import React from 'react';
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { useForm } from 'react-hook-form';

class SignIn extends React.Component {
  
const { register, handleSubmit, errors } = useForm();
const onSubmit = data => console.log(data);
console.log(errors);

  render() {
    return (
      <div>
        <Form onSubmit={handleSubmit(onSubmit)}>

            <Label>Email : </Label>
            <Input type="email" placeholder="email" name="email" ref={register({required: true, pattern: /^\S+@\S+$/i})}></Input>

            <Label>Password : </Label>
            <Input type="password" placeholder="password"  name="password" ref={register({required: true, min: 8, maxLength: 20})}></Input>

        </Form>
      </div>
    );
  }
}


export default SignIn;

我在 Class 组件中使用 react-hook-form 时遇到问题
如果可能的话,我的问题是:How to use the react-hook-form with Class Component without rewrite the code to the hook version?

您不能在 React class 组件中使用钩子。 您提供的 class 看起来很小,我认为您可以轻松地将其重写为功能组件。也许你不想,你可以提供 hoc 包装你的 class 组件的 useForm 钩子。

export const withUseFormHook = (Component) => {
    return props => {
        const form = useForm();
        return <Component {...props} {...form} />
    }       
}

并且在您的 SignIn 组件中只需执行以下操作:

export default withUseFormHook(SignIn);

来自 react-hook-form 文档:

Does it work with Class Components?

No, not out of the box. If you wanted to do this, you could build a wrapper around it and use it in your Class Component.

https://react-hook-form.com/faqs#DoesitworkwithClassComponents

在搜索越来越多之后,我使用了这个解决方案:
使用挂钩版本创建一个单独的文件:

import React from 'react'

import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { useForm } from 'react-hook-form';

const SignInHook = () => {

    const { register, handleSubmit, errors } = useForm();
    const onSubmit = data => console.log(data);
    console.log(errors);



    return (
    <>
      <div>
        <Form onSubmit={handleSubmit(onSubmit)}>

            <Label>Email : </Label>
            <Input type="email" placeholder="email" name="email" ref={register({required: true, pattern: /^\S+@\S+$/i})}></Input>

            <Label>Password : </Label>
            <Input type="password" placeholder="password"  name="password" ref={register({required: true, min: 8, maxLength: 20})}></Input>

        </Form>
      </div>
    </>
   )
}

export default SignInHook

并在我的 Class 组件中使用它:

import React from 'react';
import SignInHook from './SignInHook';

class SignIn extends React.Component {
  
  render() {
    return (
      <div>
        <SignInHook></SignInHook>
      </div>
    );
  }
}


export default SignIn;

最好和最简单的方法是将 class 组件更改为功能组件并使用 useForm 挂钩。您可以在下面找到示例代码:

import React from 'react'

import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import { useForm } from 'react-hook-form';

const SignIn = () => {

  const { register, handleSubmit, errors } = useForm();
  const onSubmit = data => console.log(data);
  console.log(errors);

  return (
    <>
      <div>
        <Form onSubmit={handleSubmit(onSubmit)}>

        <Label>Email : </Label>
        <Input type="email" placeholder="email" name="email" ref={register({required: true, pattern: /^\S+@\S+$/i})}></Input>

        <Label>Password : </Label>
        <Input type="password" placeholder="password"  name="password" ref={register({required: true, min: 8, maxLength: 20})}></Input>

        </Form>
      </div>
    </>
  )}

export default SignIn;

我遇到了同样的问题,但最后我可以这样解决:

import React from "react";
import ReactDOM from "react-dom";
import { useForm } from "react-hook-form";

import "./styles.css";

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false
    };
    this.onSubmit = this.onSubmit.bind(this);
  }

  onSubmit(data) {
    console.log(data);
  }

  render() {
    const { register, handleSubmit, errors } = this.props;
    return (
      <form onSubmit={handleSubmit(this.onSubmit)}>
        <label>Example</label>
        <input name="example" defaultValue="test" ref={register} />
        <label>ExampleRequired</label>
        <input
          name="exampleRequired"
          ref={register({ required: true, maxLength: 10 })}
        />
        {errors.exampleRequired && <p>This field is required</p>}
        <input type="submit" />
      </form>
    );
  }
}

function App(props) {
  const form = useForm();
  return <Login {...props} {...form} />;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Here 是实时沙箱。