0

I have checked the official doc and realised we cannot directly use Hooks inside the class-based component. So, I have tried the HOC method to use react-hook-form with a class-based component.

But this case is also not working in my case.

My HOC Component::

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

export const ClassHookFormWrap = (Component) => {
   const form = useForm();
   console.log("form", form, Component)
   return (props) => {
      return <Component form={form} {...props}  />;
   };
};

My class-based component::

import React from "react";
import { ClassHookFormWrap } from "./ClassHookFormWrap";

class ClassHookForm extends React.Component {
   onSubmit = (data) => {
      console.log(data);
   }
   render(){
      console.log("this.props", this.props)
      return(
         <div>Form</div>
      )
   }
}

export default ClassHookFormWrap(ClassHookForm);

The error I got inside console::

enter image description here

This is a sandbox link I have added a code sample here:: https://codesandbox.io/s/old-monad-7mkxg8?file=/src/App.js:224-237

Is there any way to use this form inside a class-based component?

2
  • 1
    Why are you still using class components in 2022? They are legacy in React Commented Nov 28, 2022 at 8:32
  • Avoid use hooks in Class Components, Update your projects with functional components if you really want to use Hooks. Commented Nov 28, 2022 at 8:47

3 Answers 3

2

Actually, hooks have to be used inside the body of the functional component. you are using it inside the HOC and HOC is a function, not a functional component, but what HOC returns is a component (here functional component). So just move the useForm inside return, instead of directly using it inside HOC. something like this.

   export const ClassHookFormWrap = (Component) => {
   return (props) => {
   const form = useForm();
   console.log("form", form, Component)
      return <Component form={form} {...props}  />;
   };
};

Let me know if it doesn't work.

Add the returning component a name to avoid eslint error.

export const ClassHookFormWrap = (Component) => {
  return function Wrap(props) {
    const form = useForm();
    console.log("form", form, Component);
    return <Component form={form} {...props} />;
  };
};
Sign up to request clarification or add additional context in comments.

2 Comments

Its not working, I already tried this before. It gives me compile time error:: Line 8:20: React Hook "useForm" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks
yeah, try to give the return Component a name.
0

Hooks are supposed to be used inside a component or inside a custom hook. A HOC is basically a function which returns a component. So in order to get this working you can move the useForm hook into the return function like this

export const ClassHookFormWrap = (Component) => {
   return (props) => {
      const form = useForm();
      console.log("form", form, Component)
      return <Component form={form} {...props}  />;
   };
};

5 Comments

ha ha.. we answered at the same time :)
ha ha :D ... technically not the same time though, beat you by a minute ;)
I am getting this error if moving useForm inside return function:: ` Line 8:20: React Hook "useForm" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks`
If you are looking for a way to move your useForm logic into a wrapper component, you can just go ahead and create a normal functional component containing the useForm logic (basically a wrapper component) and then passing the component which needs this logic as a prop or as its child.
You can also refer to this related SO thread : stackoverflow.com/questions/63291330/…
0

The best and easiest way will be to change class Component, to a functional Component and use the useForm hook.

And Still You want same i used like this (Note: this is my example you can change it as per your requirment):

Seprate File for hook version:

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

And Use it inside my Class Component:

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

class SignIn extends React.Component {

render() {
 return (
  <div>
    <SignInHook></SignInHook>
  </div>
);
}}

export default SignIn;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.