Home > Mobile >  What can happen if I don't declare a controlled component?
What can happen if I don't declare a controlled component?

Time:09-19

import React, { useState } from "react";

function App() {
  const [fName, setfName] = useState("");

  function changefName(event) {
    setfName(event.target.value);
  }

  return (
    <div className="container">
      <h1>
        Hello {fName}
      </h1>
      <form>
        <input
          name="fName"
          placeholder="First Name"
          onChange={changefName}
          value={fName}
        />
        <button>Submit</button>
      </form>
    </div>
  );
}

What can happen if I don't declare value={fName} in my input tag? I understand the difference between controlled and uncontrolled component from this post, but I don't understand the significance if I don't declare whether it is controlled or uncontrolled.

Full code here: https://codesandbox.io/s/changing-complex-state-forked-llfq2f?file=/src/components/App.jsx

CodePudding user response:

If you do not use a value prop, the input is uncontrolled. Although you have an onChange handler, the value of the input is managed only from the DOM, so your fName state may not necessarily be the same as the value in the input. For example, if you call setFName elsewhere - outside the onChange - the input in the DOM will not reflect the state change.

For example, the button below does not result in the input value changing:

function App() {
  const [fName, setfName] = React.useState("");

  function changefName(event) {
    setfName(event.target.value);
  }

  return (
    <div className="container">
      <button onClick={() => setfName('foo')}>Change name to foo</button>
      <h1>
        Hello {fName}
      </h1>
      <form>
        <input
          name="fName"
          placeholder="First Name"
          onChange={changefName}
        />
        <button>Submit</button>
      </form>
    </div>
  );
}

ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div class='react'></div>

It's best to choose one approach and stick with it, for a particular state and input: either have a value and an onChange that maps to that state value, or don't have either. (You can still have an onChange in an uncontrolled component - just don't have it change a state text value too, otherwise you could easily run into bugs like in the snippet above.)

CodePudding user response:

Nothing, it will set the input tag's default value and controller. You will no longer have the input state change, it will be a declared but unused hook (fname).

But the onchange event will still be called and populated within your function (changefName), see that it takes the target.value, which is the value of the input (which has its own controller).

  • Related