1

Form validation not working with React strap and React hook form version 7. In the above sandbox project, when I click the submit button without entering the text to the bio input getting an error bio field is required. then when I type on that field, the error message, not disappear. Version 7 working very well with normal HTML forms and elements. but getting some conflict with reactstrap.

React version : 17.2 React hook form version : 7.22 Reactstrap version : 9.0

import "./styles.css";
import { Form, FormGroup, Input, Label, Button } from "reactstrap";
import * as Yup from "yup";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";

export default function App() {
  const schema = Yup.object().shape({
    bio: Yup.string().required()
  });

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors }
  } = useForm({
    resolver: yupResolver(schema)
  });

  const submitHandle = (data) => {
    console.log(data);
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Form onSubmit={handleSubmit(submitHandle)} onReset={reset}>
        <FormGroup>
          <Label for="bio">Bio</Label>
          <Input id="bio" name="bio" type="text" {...register("bio")} />
          {errors.bio && <p className="invalid">{errors.bio.message}</p>}
        </FormGroup>
        <FormGroup>
          <br/>
          <Button color="primary">Save</Button>
        </FormGroup>
      </Form>
    </div>
  );
}

Code sandbox : https://codesandbox.io/s/ancient-smoke-0ccbn

1 Answer 1

4

I didn't find anything in your sandbox link, but your problem is because of the ref, react-hook-form need to access ref of input, while reactstrap's Input component exposes ref by innerRef prop, so there are two solutions to solve your problem:

1- manually register field like this:

default function App() {
  ...
  const {ref,...bio} = register('bio');
  return (
   <Form onSubmit={handleSubmit(submitHandle)} onReset={reset}>
      <FormGroup>
        <Label for="bio">Bio</Label>
        <Input id="bio" name="bio" type="text"  {...bio} innerRef={ref}/>
        {errors.bio && <p className="invalid">{errors.bio.message}</p>}
      </FormGroup>
    </Form>
  );
}

2- Use the Controller component, which will take care of the registration process, like this:

default function App() {
  ...
 const {
  handleSubmit,
  reset,
  control,
  formState: { errors },
 } = useForm({
  resolver: yupResolver(schema),
  defaultValues: { bio: '' },
 });
  ...
  return (
   <Form onSubmit={handleSubmit(submitHandle)} onReset={reset}>
      <FormGroup>
        <Label for="bio">Bio</Label>
        <Controller
          id="bio"
          name="bio" 
          control={control}
          render={({ field }) => <Input {...field} />}
        />
        {errors.bio && <p className="invalid">{errors.bio.message}</p>}
      </FormGroup>
    </Form>
  );
}
Sign up to request clarification or add additional context in comments.

1 Comment

Hai, this does not work with multiple fields.

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.