头图

The text starts here~

Overview

When the value of ---812be9af1ed6d6dd848c1d86baa11043 input is initialized to undefined , but later changed to a different value, the "A component is changing an uncontrolled input to be controlled" warning is generated. To fix this, initialize the value of input to an empty string. For example, value={message || ''} .

component-changing-uncontrolled-input.png

Here is an example to show how the error occurs.

 import {useState} from 'react';

const App = () => {
  // 👇️ didn't provide an initial value for message
  const [message, setMessage] = useState();

  const handleChange = event => {
    setMessage(event.target.value);
  };

  return (
    <div>
      <input
        type="text"
        id="message"
        name="message"
        onChange={handleChange}
        value={message}
      />
    </div>
  );
};

export default App;

The problem with the code above is that the message variable is initialized to undefined because we didn't pass it an initial value in the useState hook.

Alternate value

One way to fix this error is to provide an alternate value if the value of undefined input ---39d9cb8c45367b64eb3712b20f0b5650--- .

 import {useState} from 'react';

const App = () => {
  const [message, setMessage] = useState();

  const handleChange = event => {
    setMessage(event.target.value);
  };

  // 👇️  value={message || ''}

  return (
    <div>
      <input
        type="text"
        id="message"
        name="message"
        onChange={handleChange}
        value={message || ''}
      />
    </div>
  );
};

export default App;

We use the logical AND (||) operator, which returns the value on the right if the left side of the operator is false (say undefined ).

If the message variable's value is stored as undefined , we return the empty string as an alternate value.

useState

Another solution is to pass the initial value for the state variable in the useState hook.

 import {useState} from 'react';

const App = () => {
  // 👇️ pass an initial value to the useState hook
  const [message, setMessage] = useState('');

  const handleChange = event => {
    setMessage(event.target.value);
  };

  return (
    <div>
      <input
        type="text"
        id="message"
        name="message"
        onChange={handleChange}
        value={message}
      />
    </div>
  );
};

export default App;

Passing the initial value in the useState hook avoids the warning because the message variable has not changed from undefined to a value.

The reason for the warning is that when the message variable is initialized without a value, it is set to undefined .

Passing an attribute like value={undefined} is equivalent to not passing the value attribute at all.

Once the user starts typing in input bf10735160844a9f534c263b088cdc7e---, the value attribute is passed to the input form and the input changes from uncontrolled to controlled, which is Not allowed.

defaultValue

Note that if you use an uncontrolled input form, you should use the defaultValue attribute instead of value .

 import {useRef} from 'react';

const App = () => {
  const inputRef = useRef(null);

  function handleClick() {
    console.log(inputRef.current.value);
  }

  return (
    <div>
      <input
        ref={inputRef}
        type="text"
        id="message"
        name="message"
        defaultValue="Initial value"
      />

      <button onClick={handleClick}>Log message</button>
    </div>
  );
};

export default App;

uncontrolled-input-default-value.gif

The above example uses uncontrolled input . Note that the input form does not set the onChange or value attribute.

You can use the defaultValue attribute to pass initial values for uncontrolled input . However, this step is not necessary, you can omit this property if you don't want to set the initial value.

When using the uncontrolled input form, we use ref to access input element. Whenever the user clicks the button in the example, the value of the uncontrolled input is logged.

You should not set the value property for the uncontrolled input ---, as this will make the input form immutable and you will not be able to type in it.


chuck
300 声望41 粉丝