How is React handling renders for this uncontrolled input element?

Viewed 41

I'm going through React's beta docs and would like to better understand how react handles user's interactions with the UI. Specifically with this non-controlled input field.

Note:

  • the input field is not disabled
  • new input values should not trigger a render, because it's not changing any state (local variables are ignored)

So, then why is the change not reflected in the UI???

The code is bellow, and an interactive "sandbox" can be found here: https://beta.reactjs.org/learn/state-a-components-memory under challenge #2 at the bottom of the page.

export default function Form() {
  let firstName = '';
  let lastName = '';

  function handleFirstNameChange(e) {
    firstName = e.target.value;
  }

  function handleLastNameChange(e) {
    lastName = e.target.value;
  }

  function handleReset() {
    firstName = '';
    lastName = '';
  }

  return (
    <form onSubmit={e => e.preventDefault()}>
      <input
        placeholder="First name"
        value={firstName}
        onChange={handleFirstNameChange}
      />
      <input
        placeholder="Last name"
        value={lastName}
        onChange={handleLastNameChange}
      />
      <h1>Hi, {firstName} {lastName}</h1>
      <button onClick={handleReset}>Reset</button>
    </form>
  );
}

To be clear, I'm not asking how to solve this problem; I know how to hook it up and fix it with state. I am interested in what's preventing the input field from updating with a new value.

On initial render it receives the empty string as its value. But then why doesn't it change when a user types?

Here's two non-react input fields, one with a value attribute, and one where the value is set by JS. Both can be modified:

<input type="text" value="editable">

<input type="text" id="input2">

<script>
 document.getElementById('input2').value = "also editable"
</script>

So, why isn't the input editable in react?

1 Answers

There are two reasons for a component to render:

  • It’s the component’s initial render.
  • The component’s (or one of its ancestors’) state has been updated.

In your example, the second condition is not met and react has no way of knowing your input values changed, it does not re render, and so does not commit changes to the DOM.
Note that react is wrapping event handlers, it does not work exactly like vanilla JavaScript

Related