javascripthtmlreactjsuse-form

How can i get the value of a select in react using React Hook Form?


The main problem in my code is:
1 - My function filtra_pavimento is not being called; So, i suppose my onchange is not working well. I heard something about getValues, but i'm not so sure about it. I also don't know if i have to use onChange method or other that i'm not using.

Can anyone helpe me? my code is:

import { useForm } from "react-hook-form";
import { isEmail, isDate } from "validator";

const GoodForm = () => {
  const {
    register,
    handleSubmit,
    getValues,
    onChange,
    formState: { errors },
  } = useForm();

  const filtra_pavimento = () => {
    console.log("cheguei aqui")
    const valor = getValues("mysel")
  }

  return (
    <div className="app-container">

      <div className="form-group">
        <label>My Select</label>
        <select
          className={errors?.mysel && "input-error"}
          defaultValue="0"
          onChange={filtra_pavimento}
          {...register("mysel", { validate: (value) => value !== "0" })}
        >
          <option value="0">Select some option...</option>
          <option value="blebleble">blebleble</option>
          <option value="blablabla">blablabla</option>
         
        </select>

        {errors?.mysel?.type === "validate" && (
          <p className="error-message">É obrigatório preencher esse campo.</p>
        )}
      </div>
  </div>
)

Solution

  • When you register the field, react-hook-form is providing its own onChange function, overwriting the one you wrote and that's why is not being call.

    One option is to subscribe to the specific field using the watch function that comes from useForm hook in case you need to perform some operation with the value:

    import { useEffect } from "react";
    import { useForm } from "react-hook-form";
    import { isEmail, isDate } from "validator";
    
    const GoodForm = () => {
      const {
        register,
        handleSubmit,
        getValues,
        onChange,
        formState: { errors },
        watch,
      } = useForm();
    
      const watchMysel = watch("mysel")
    
      useEffect(() => {
        const filtraPavimento = () => {
          console.log('mysel value', watchMysel);
        }
        filtraPavimento()
      }. [watchMysel]);
    
      return (
        <div className="app-container">
          <div className="form-group">
            <label>My Select</label>
            <select
              className={errors?.mysel && "input-error"}
              defaultValue="0"
              {...register("mysel", { validate: (value) => value !== "0" })}
            >
              <option value="0">Select some option...</option>
              <option value="blebleble">blebleble</option>
              <option value="blablabla">blablabla</option>
            </select>
            {errors?.mysel?.type === "validate" && (
              <p className="error-message">É obrigatório preencher esse campo.</p>
            )}
          </div>
      </div>
    )
    

    If React.useEffect is not suitable for you, you still can use your own onChange function, but you have to use the useForm one to be reflected in the state (or use other functions like setValue to update it yourself). However, the react-hook-form docs do not advise it because it often comes with a significant impact on performance.

    Check the documentation of useForm here: https://react-hook-form.com/api/useform/watch/

    Hope that helps!