Mudassir Ali Mudassir Ali - 2 months ago 14
Javascript Question

Behind the scenes explanation of react controlled components

Here's the code for a controlled component from React's documentation.

class CustomInput extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
}

render() {
console.log('render called');
return (
<input type="text" value={this.state.value} />
);
}
}


This renders a
<input>
field which I cannot edit. I am just curious of how this is wired internally by react. Who's blocking my
keypress
events? Does react hook up a
keypress
event handler with
e.preventDefault()
to ensure I cannot type anything?

Codepen URL: https://codepen.io/mudassir0909/pen/MvQwGm?editors=0010

Answer Source

Nothing's blocking any keypresses. The reason it seems 'non-editable' is because it always has the same value. React has a concept of the virtual DOM, a 'fake' and simplified version of the real DOM that's used to check for component changes. If there are component changes, the virtual DOM sees this as it does a efficient diff check to make sure there was an update and the real DOM is updated. This is what the key prop is used for when mapping children.

This is way more efficient for rerendering as it gets rid of unnecessary rerendering and DOM modifications which are expensive as the browser needs to parse the new HTML, reapply stylesheets, redraw, etc. React also only rerenders a subtree, not the whole tree.

Now, if you look at your component, it always has the same value in state, an empty string. Whenever you try to type, nothing happens because state is never updated. Since state's never updated React never sees the need to do a diff check and rerender. Thus no keypress events are being prevented, it's just that React doesn't see a change and doesn't update the DOM, and in turn, the input.


Note: This doesn't apply to uncontrolled inputs because their value property isn't set explicitly by component state, so it's not React's job to manage the input's state. The input itself is allowed to manage its internal state. Once you tie an input to component state, it's React's job, and yours, to control the input value.