2
votes

I have a very simple demo react app. It consists of a Semantic UI React Form with just one Input.

I am trying to use React Hook Form to validate it on blur. The field is valid only if it contains more than ten characters.

By default the validation fires on submit, but you are supposed to be able to have the form validated on touched, blur or change events by passing in arguments to useForm, see the docs.

In my example below the validation still only fires on submit. Why is that, and what can I do to fix it?

//imports

const App = () => {
  const { register, setValue, handleSubmit, errors } = useForm({
    mode: "onBlur"
  });

  const handleChange = (e, { name, value }) => { setValue(name, value) };

  const onSubmit = (value) => {
    alert("submitted successfully");
    console.log(value);
  };

  useEffect(() => {
    register({ name: "input" }, { required: true, minLength: 10 });
  });

  return (
    <Form className="App" onSubmit={handleSubmit(onSubmit)}>
      <Input
        name="input"
        className="field"
        placeholder="Type here"
        onChange={handleChange}
        error={!!errors.input}
      ></Input>
      <Button type="submit">Submit</Button>
    </Form>
  );
};

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

Here is a CodeSandbox link if that helps: https://codesandbox.io/s/react-hook-form-with-semantic-ui-react-z59p2?file=/src/index.js

1

1 Answers

1
votes

Looks like you just need to add trigger to handleChange after the setValue.

https://react-hook-form.com/api/useform/trigger

import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import { Form, Input, Button } from "semantic-ui-react";
import { useForm } from "react-hook-form";
import "semantic-ui-css/semantic.min.css";

const App = () => {
  const { register, setValue, handleSubmit, errors, trigger } = useForm({
    mode: "onBlur"
  });

  const handleChange = (e, { name, value }) => {
    setValue(name, value);
    trigger(name);
  };

  const onSubmit = (value) => {
    alert("submitted successfully");
    console.log(value);
  };

  useEffect(() => {
    register({ name: "input" }, { required: true, minLength: 10 });
  }, []);

  return (
    <Form className="App" onSubmit={handleSubmit(onSubmit)}>
      <Input
        name="input"
        className="field"
        placeholder="Type here"
        onChange={handleChange}
        error={!!errors.input}
      ></Input>
      <Button type="submit">Submit</Button>
    </Form>
  );
};

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

Fork of your CodeSandBox link: https://codesandbox.io/s/react-hook-form-with-semantic-ui-react-forked-ho7ut?file=/src/index.js


Updated your script to use onBlur instead of onchange:

import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import { Form, Input, Button } from "semantic-ui-react";
import { useForm } from "react-hook-form";
import "semantic-ui-css/semantic.min.css";

const App = () => {
  const { register, setValue, handleSubmit, errors, trigger } = useForm({
    mode: "onBlur"
  });

  const handleChange = (e) => {
    e.persist();
    setValue(e.target.name, e.target.value);
    trigger(e.target.name);
  };

  const onSubmit = (value) => {
    alert("submitted successfully");
    console.log(value);
  };

  useEffect(() => {
    register({ name: "input" }, { required: true, minLength: 10 });
  }, []);

  return (
    <Form className="App" onSubmit={handleSubmit(onSubmit)}>
      <Input
        name="input"
        className="field"
        placeholder="Type here"
        onBlur={handleChange}
        error={!!errors.input}
      ></Input>
      <Button type="submit">Submit</Button>
    </Form>
  );
};

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

https://codesandbox.io/s/react-hook-form-with-semantic-ui-react-forked-ho7ut?file=/src/index.js