Reputation: 17
I am learning React State. Here I am dynamically changing the value of according to user input using State().
import React from "react";
function App() {
var [fullName, setFullName] = React.useState({
fName: "",
lName: ""
});
return (
<div className="container">
<h1>
Hello {fullName.fName} {fullName.lName}
{/* {console.log(fullName)} */}
</h1>
<form>
/*//////////////////////////////////////////this below is correct segment and works*/
{/* <input
onChange={(event) => {
setFullName({ fName: event.target.value, lName: fullName.lName });
}}
name="fName"
placeholder="First Name"
/>
<input
onChange={(event) => {
setFullName({ fName: fullName.fName, lName: event.target.value });
}}
name="lName"
placeholder="Last Name"
/> */}
/*////////////////////////////////////////////////////////////////////////////////*/
Here setFullName seems to be taking an object as parameter, so why is the code not working when i update the value of fullName(object) and passing it into setFullName???
<input
onChange={(event) => {
fullName.fName = event.target.value;
setFullName(fullName);
}}
name="fName"
placeholder="First Name"
/>
<input
onChange={(event) => {
fullName.lName = event.target.value;
setFullName(fullName);
}}
name="lName"
placeholder="Last Name"
/>
<button>Submit</button>
</form>
</div>
);
}
export default App;
Does the input has to be a object declared inside State ??
Upvotes: 0
Views: 1697
Reputation: 121
The best practice is to attach a name handler to the input tag and grab it using event.name to update the state. As others stated, you can't mutate state directly, you have to update it like this.
const [fullName, setFullName] = useState({ fName: "", lName: "" })
const handleChange = e => {
setFullName({
...fullName,
[event.target.name]: event.target.value
})
}
<input
name="fName"
placeholder="First Name"
onChange={handleChange}
/>
<input
name="lName"
placeholder="Last Name"
onChange={handleChange}
/>
Upvotes: 1
Reputation: 111
Yes, as you are expecting an object in useState then you can only assign an object of type
{fName: "abc", lName: "xyz"}
Upvotes: 1
Reputation: 605
React doesn't allow you to directly update the state value. Here's why outsite link
Upvotes: 1
Reputation: 2037
It's not working because you are trying to mutate the state directly. This is not allowed.
onChange={(event) => {
//Get the current state, shallow copy it and then override the property with your new value
setFullName(prevState => ({
...prevState,
lName: event.target.value
}));
}}
Upvotes: 2
Reputation: 414
You shouldn't mutate the state object directly. The fact that you are setting the fullName
state object is wrong. Instead try something like this;
onChange={(event) => {
const tempState = {...fullName}
tempState.lName = event.target.value;
setFullName(tempState)
}}
The difference here is, I created a copy of the current state, then mutated the copy object (thus didn't directly mutate the state object which is a hard NO in react) and then set the state accordingly.
Upvotes: 4