DukeSmellington
DukeSmellington

Reputation: 83

React input handleInputChange() not working

Here is a small extract from a contact form I am making in a personal project. In this condition the handleInputChange() on the email input works as expected (I can free-type in the field and the field updates dynamically).

const FeedbackForm = () => {
  let [formValues, setFormValues] = useState({ email: "" });

  const handleInputChange = (target) => {
    const updatedFormValues = {
      ...formValues,
      [target.name]: target.value,
    };
    setFormValues(updatedFormValues);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
  };

  return (
      <form onSubmit={handleSubmit}>
          <input
            name="email"
            value={formValues.email}
            onChange={(e) => handleInputChange(e.target)}
          />
        <button type="submit">Submit</button>
      </form>
  );
};

Later in the development I decided I wanted to conditionally show/hide the email field so I abstracted it out to a separate component with a boolean prop to toggle the visibility of the element.

const FeedbackForm = ({
  emailFormFieldEnabled,
}) => {
  let [formValues, setFormValues] = useState({ email: "" });

  const handleInputChange = (target) => {
    const updatedFormValues = {
      ...formValues,
      [target.name]: target.value,
    };
    setFormValues(updatedFormValues);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
  };

  const EmailFormField = ({ visible }) => {
    if (!visible) {
      return null;
    }
    return (
        <input
          name="email"
          value={formValues.email}
          onChange={(e) => handleInputChange(e.target)}
        />
    );
  };

  return (
      <form onSubmit={handleSubmit}>
            <EmailFormField visible={emailFormFieldEnabled} />
        <button type="submit">
            Submit
        </button>
      </form>
  );
};

The toggling visibility works but this appears to have broken the handleInputChange() function. I can no longer free type in the input. I can select the input and type a single character but no more. If I want to type multiple characters in the field (like an email address, for example) I have to re-select the field to enter each character.

Any idea what I might be doing wrong?

Upvotes: 1

Views: 770

Answers (1)

Drew Reese
Drew Reese

Reputation: 203466

Issue

You have declared the EmailFormField component inside another component, so it's redeclared each render cycle. In other words, you are mounting a new instance each render cycle. Remounting the EmailFormField loses any focus the previous "instance" had.

Solution

Declare EmailFormField outside the component and pass all the value and onChange props in.

Example:

const EmailFormField = ({ visible, value, onChange }) => {
  if (!visible) {
    return null;
  }
  return <input name="email" value={value} onChange={onChange} />;
};

const FeedbackForm = ({ emailFormFieldEnabled }) => {
  let [formValues, setFormValues] = useState({ email: "" });

  const handleInputChange = (e) => {
    const updatedFormValues = {
      ...formValues,
      [e.target.name]: e.target.value
    };
    setFormValues(updatedFormValues);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit}>
      <EmailFormField
        onChange={handleInputChange}
        visible={emailFormFieldEnabled}
        value={formValues.email}
      />
      <button type="submit">Submit</button>
    </form>
  );
};

Edit react-input-handleinputchange-not-working

Upvotes: 1

Related Questions