A component is changing an uncontrolled input to be controlled

A component is changing an uncontrolled input to be controlled
const Component = () => {
  // Solution: Use an empty string ( not undefined or null ) for the default value.
  const [name, setName] = useState(""); 
  // other component code
}

A description of why is below:

One of the common challenges developers face when working with React is understanding the difference between controlled and uncontrolled inputs.

A controlled input is managed by the component’s state, ensuring that any modifications to the input are seamlessly reflected in the component's state.

Conversely, an uncontrolled input lacks a specific associated state. Instead, developers can directly access the input's value through a ref or the DOM.

In every controlled text input we must pass the value and onChange props to the component, like this:

// Controlled component sample
const myTextComponent = () => {
  const [name, setName] = useState("");
  const onChange = (e) => setValue(e.target.value);
  return (<input type="text" value={name} onChange={handleChange} />);
}

When using controlled components in React, it's essential to ensure that the value ​attribute is not null or undefined. Failing to provide a valid value attribute can trigger a well-known warning.

A component is changing an uncontrolled input to be controlled

To handle controlled inputs effectively, it's crucial to specify an empty string as the default value in case the value is absent. For instance, setName(name ?? "") can be utilized to set the correct value retrieved from an API.

Unlike other input types, checkboxes in React utilize the checked attribute instead of value to determine their state. When handling checkbox inputs, it's important to use e.target.checked instead of 'e.target.value' to access the checkbox's state. This is because checkboxes have a binary state (checked or unchecked) rather than a value.

For uncontrolled inputs, we don’t need to specify a value. However, we can set a defaultValue for text inputs or defaultChecked checkboxes. Optionally, we can also use a ref to access the value. Here’s an example:

const UncontrolledComponent = () => {
  const inputRef = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(inputRef.current.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
};

Summary:

Controlled inputs are useful when you need to validate fields immediately and provide additional hints based on input values.

Uncontrolled inputs are ideal when immediate validation is not required, such as in a large form with multiple fields. In this case, you can submit the form without adding a state for each field.

In addition to clarifying the differences between controlled and uncontrolled inputs, it's important to address common warnings such as A component is changing an uncontrolled input to be controlled in React. This warning typically occurs when a component that was initially uncontrolled is later converted to a controlled component. To resolve this issue, ensure that all necessary props (such as value​ and onChange​) are properly passed to the component from the beginning, or consider initializing the component as controlled from the outset.

Thank you for reading!