I got the following warning when using controlled components, despite having set the initial states: Warning: A component is changing a controlled input of type undefined to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
Here is my code:
import React, { useState } from "react";
function App() {
const [fullName, setFullName] = useState({
fName: "",
lName: ""
});
function handleChange(event) {
const { value, name } = event.target;
setFullName(prevValue => {
if (name === "fName") {
return {
fName: value,
lName: prevValue.lName
};
} else if (name === "lName") {
return {
fName: prevValue.fName,
lname: value
};
}
});
}
return (
<div className="container">
<h1>
Hello {fullName.fName} {fullName.lName}
</h1>
<form>
<input
name="fName"
onChange={handleChange}
placeholder="First Name"
value={fullName.fName}
/>
<input
name="lName"
onChange={handleChange}
placeholder="Last Name"
value={fullName.lName}
/>
<button>Submit</button>
</form>
</div>
);
}
export default App;
If I type John as the fName and Doe as the lName in the inputs, the headline should be Hello John Doe, but I just got Hello John with the warning. Using the condition below will get rid of the warning, but I just get Hello John again:
value={fullName.lName || ""}
How to get both fName and lName displayed at the same time without the warning?
This is happening because of a typo. Change :
else if (name === "lName") {
return {
fName: prevValue.fName,
lname: value
};
}
to:
else if (name === "lName") {
return {
fName: prevValue.fName,
lName: value // notice 'n' was in lowercase.
};
}
Also, a more concise way to go about it (in my opinion) would be:
setFullName((prevValue) => ({
...prevValue, [name] : value
}));
Working example : here