DEV Community

Helder Burato Berto
Helder Burato Berto

Posted on • Originally published at helderberto.com

Controlled vs Uncontrolled Elements

When working with React, you will notice often used naming called Controlled and Uncontrolled.

So, what do it mean? Let's dive into it.

Uncontrolled Element

This type of element is not managed by React.

In the following example, you have an uncontrolled input element:

import React from 'react'

export default function UncontrolledInput() {
  return (
    <input
      value="Empty Value"
      onChange={() => console.log('It wont update the value.')}
    />
  )
}
Enter fullscreen mode Exit fullscreen mode

Notice the component isn't doing anything, just printing an empty value Empty value.

You can't update, nor delete the value.

Let's add an event handler for updating the value state:

import React from 'react'

export default function UncontrolledInput() {
  const [value, setValue] = React.useState()

  return (
    <>
      <input
        value={value}
        onChange={(event) => setValue(event.target.value)}
      />
      <p>Current value: {value}</p>
    </>
  )
}
Enter fullscreen mode Exit fullscreen mode

Notice that even if we can update the input now, you have a warning on your browser console. Like the following:

Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Why is this happening?

Since the default value is not initialized in the useState(), React will consider the initial value as undefined, so it means the input still uncontrolled at the first render.

It only will be controlled when the user starts typing on the input.

Controlled Element

The Controlled element is an element that is managed the event and values by React.

Let's create an input managed by React:

import React from 'react'

export default function ControlledInput() {
  const [value, setValue] = React.useState('') // Start as an empty string

  return (
    <>
      <input
        value={value}
        onChange={(event) => setValue(event.target.value)}
      />
      <p>Current name: {value}</p>
    </>
  )
}
Enter fullscreen mode Exit fullscreen mode

Since you set it as an empty string, it will be a controlled element.

When the user starts typing in the input, the onChange event updates the value of name from '' to a new string.

Wrapping Up

It's a common mistake updating uncontrolled elements to controlled raising this kind of warning.

When you understand how it works, it's easier to avoid these issues.

Top comments (4)

Collapse
 
brense profile image
Rense Bakker

Actually, as soon as you add a value to an input in React, it becomes a controlled input (you become responsible for tracking its state). Uncontrolled inputs look like this:

function SomeForm(){
  return <form>
    <input onChange={evt => console.log(evt)} />
  </form>
}
Enter fullscreen mode Exit fullscreen mode

The onChange event triggers when the user types in the input field, but we don't pass any value to the input, so the input manages its state internally.

Collapse
 
helderberto profile image
Helder Burato Berto

You’re right, it becomes a controlled input, but it will triggers a warning since it wasn’t a controlled with the initial value as “undefined”. Thanks for commenting!

Collapse
 
naucode profile image
Al - Naucode

Great article, you got my follow, keep writing!

Collapse
 
helderberto profile image
Helder Burato Berto

I really appreciate that.