Sharing is caring: Two-way data binding in React Js.

Pato Montecchiarini
3 min readApr 19, 2021

Hi! 👋 Have you ever gotten that Warning while developing forms in React that REALLY likes to use the word Controlled? 👇

A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Not mine. Borrowed from weknowmemes.com

Whether you were asking yourself what that was about, or (like me) googled the solution and got rid of it as fast as you could, today I’d like to give you a bit of context as to what that warning is referring to.

What IS two-way data binding? 🤔

When building a form, whether we use inputs, text areas select, or so on, we need to gather the user input.

We need to know what value the user entered, to use it somewhere else. And that’s where data binding comes in: We connect and synchronize, a data source with a consumer of that data.

Ok, but HOW? 😕

In React, as of v15, we need to explicitly set the value and change handler in whatever form element we need to gather data from (which I’m guessing would be all of them, unless you like to make people checkboxes just for fun).

For this article, we will use input and useState Hooks to implement the two-way binding.

  1. Set the state with useState hook.
const RegisterForm = () => {
const[myValue, setMyValue] = useState('');
return <form>
<input type="text"/>
<button>SUBMIT</button>
</form>
};
export default RegisterForm;

2. The input’s value property will be bound to the state of the myValue variable.

const RegisterForm = () => {
const[myValue, setMyValue] = useState('');
return <form>
<input type="text" value={myValue}/>
<button>SUBMIT</button>
</form>
};
export default RegisterForm;

3. We will add an onChange event listener, to listen for any changes made by the user to the input element. onChange will point to a handler that will set the myValue variable to the new updated value.

const MyForm = () => {
const[myValue, setMyValue] = useState('');
const valueHandler = (event) => {
setMyValue(event.target.value);
};
return <form>
<input type="text" value={myValue} onChange={valueHandler}/>
<button>SUBMIT</button>
</form>
};
export default MyForm;

By adding the two-way binding, whenever we submit the form, we will be able not only to gather and pass the data the user entered but also once we’ve done that, we can modify the value in our input to go back to our desired initial value.

What does ANY of this have to do with the Controlled/Uncontrolled warning? 🥱

As it turns out a controlled react component is a form element whose value is controlled by React, which is what happens when you apply two-way data binding. While the uncontrolled components data is handled by the DOM itself.

Meaning that whenever you get that wordy error message, what React is trying to warn you about is that your code is changing a form element from being controlled by React, to being controlled by the DOM (or vice-versa), and that's a no-go with React.

not mine. from http://www.reactiongifs.com/

I know. 🤯.

--

--

Pato Montecchiarini

I’m a web & mobile developer. Love all CSS related things. Coding in JS and Dart.