Input loses focus when typing one character in React Hooks

I am using the useForm hook to rewrite a form in my React application. When I type one character into the input, the input loses focus. I believe this is because the component isn’t aware of the internal changes, but I’m not sure how to resolve the issue.

import React, { useState } from "react";

export default function useForm(defaultState, label) {
  const [state, setState] = useState(defaultState);

  const FormComponent = () => (
    <form>
      <label htmlFor={label}>
        {label}
        <input
          type="text"
          id={label}
          value={state}
          placeholder={label}
          onChange={e => setState(e.target.value)}
        />
      </label>
    </form>
  );

  return [state, FormComponent, setState];
}
function App() {
  const [formValue, Form, setFormValue] = useForm("San Francisco, CA", "Location");

  return (
    <Fragment>
      <h1>{formValue}</h1>
      <Form />
    </Fragment>
  );
}

I am having an issue with input focus in my React application. When I type one character into the input, it loses focus. This is likely due to the outside component not being aware of the internal changes. The provided fenced code blocks are the useForm hook and the component that uses it. How can I resolve this issue?

The issue with losing focus when typing one character into the input is caused by the fact that the FormComponent is re-rendered every time the parent component re-renders. To resolve this issue, you can use the React.memo function to memoize the FormComponent and prevent unnecessary re-renders.

Here’s the updated code:

import React, { useState } from "react";

export default function useForm(defaultState, label) {
  const [state, setState] = useState(defaultState);

  const FormComponent = React.memo(() => (
    <form>
      <label htmlFor={label}>
        {label}
        <input
          type="text"
          id={label}
          value={state}
          placeholder={label}
          onChange={e => setState(e.target.value)}
        />
      </label>
    </form>
  ));

  return [state, FormComponent, setState];
}

By wrapping FormComponent with React.memo, it will only re-render when its props or state change, preventing unnecessary re-renders and preserving the input focus.