myTest532 myTest532
myTest532 myTest532

Reputation: 2391

React Input with useForm onChange not firing

I have a Input with a useForm register where the onChange is not working.

import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { Form, FormGroup, Input } from "reactstrap";

const App = () => {
  const [loginData, setLoginData] = useState({
    email: null,
    password: null
  });
  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm();

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

  return (
    <div className="row">
      <div className="col-sm-12">
        <Form onSubmit={handleSubmit(submitForm)}>
          <FormGroup className="has-wrapper">
            <Input
              type="email"
              name="email"
              id="email"
              className="has-input input-lg"
              placeholder="Enter Email Address"
              value={loginData.email}
              onChange={(e) => console.log(e)}
              {...register("email", { required: true })}
              aria-invalid={errors.email ? "true" : "false"}
            />
            <span className="has-icon">
              <i className="ti-email"></i>
            </span>
            {errors.email && (
              <span style={{ color: "red" }} role="alert">
                required
              </span>
            )}
          </FormGroup>
        </Form>
      </div>
    </div>
  );
};

export default App;

When I change the value of email, the onChange is not being called. https://codesandbox.io/s/gracious-chatterjee-3e8i0

Upvotes: 1

Views: 6300

Answers (1)

knoefel
knoefel

Reputation: 6989

You need to use the <Controller /> component, as register isn't working with external controlled components like your <Input /> component. Check this section in the docs for more information.

You can also omit useState here and let RHF handle the state changes for you.

const App = () => {
  const {
    control,
    handleSubmit,
    formState: { errors }
  } = useForm({
    defaultValues: { email: "", password: "" }
  });

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

  return (
    <div className="row">
      <div className="col-sm-12">
        <Form onSubmit={handleSubmit(submitForm)}>
          <FormGroup className="has-wrapper">
            <Controller
              name="email"
              control={control}
              defaultValue=""
              rules={{ required: true }}
              render={({ field: { ref, onChange, ...field } }) => (
                <Input
                  {...field}
                  type="email"
                  id="email"
                  innerRef={ref}
                  onChange={({ target: { value } }) => onChange(value)}
                  className="has-input input-lg"
                  placeholder="Enter Email Address"
                  aria-invalid={!!errors.email}
                />
              )}
            />
            <span className="has-icon">
              <i className="ti-email"></i>
            </span>
            {errors.email && (
              <span style={{ color: "red" }} role="alert">
                required
              </span>
            )}
          </FormGroup>
          <input type="submit" />
        </Form>
      </div>
    </div>
  );
};

Edit competent-brown-t1bk3

Upvotes: 2

Related Questions