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
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.)