Creating a function that will update my state based to edit user profile information based on input submitted on a form.
My function is only updating the last input I entered in my form. Here is a snippet of my code
let { user,logOutUser,updateProfile } = useContext(AuthContext)
//store users in state
const[profileUser, setProfileUser] = useState({user})
//handle form submission
const handleSubmit = e => {
console.log(user)
const updatedProfile = {
username: profileUser.username,
email: profileUser.email,
first_name: profileUser.first_name,
last_name: profileUser.last_name,
city: profileUser.city,
country: profileUser.country
}
console.log(updatedProfile)
e.preventDefault();
}
and here's my form:
<Form>
<Row>
<Col className="pr-1" md="6">
<FormGroup>
<label>Username</label>
<Input
placeholder="Username"
type="text"
name="username"
onChange={ e => setProfileUser({'username': e.target.value}) }
/>
</FormGroup>
</Col>
<Col className="pr-1" md="6">
<FormGroup>
<label htmlFor="exampleInputEmail1">
Email address
</label>
<Input
placeholder="Email"
type="email"
name="email"
value={profileUser.email}
onChange={ e => setProfileUser({'email': e.target.value}) }
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col className="pr-1" md="6">
<FormGroup>
<label>First Name</label>
<Input
placeholder="Enter your first name"
type="text"
name="first_name"
onChange={ e => setProfileUser({'first_name': e.target.value}) }
/>
</FormGroup>
</Col>
<Col className="pr-1" md="6">
<FormGroup>
<label>Last Name</label>
<Input
placeholder="Enter your last name"
type="text"
name="last_name"
onChange={ e => setProfileUser({'last_name': e.target.value}) }
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col className="pr-1" md="6">
<FormGroup>
<label>City</label>
<Input
placeholder="Enter your city"
type="text"
name="city"
onChange={ e => setProfileUser({'city': e.target.value}) }
/>
</FormGroup>
</Col>
<Col className="pr-1" md="6">
<FormGroup>
<label>Country</label>
<Input
placeholder="Enter your country"
type="text"
name="country"
onChange={ e => setProfileUser({'country': e.target.value}) }
/>
</FormGroup>
</Col>
<div className="update ml-auto mr-auto">
<Button
className="btn-round"
color="primary"
type="submit"
onClick={handleSubmit}
>
Update Profile
</Button>
</div>
</Row>
</Form>
This is what I have in users:
bio: ""
city: ""
country: ""
exp: *****
first_name: ""
iat: *****
jti: "******"
last_name: ""
photo: "\"profile/2022/03/27/emmanuelpic.png\""
token_type: "access"
user_id: 1
username: "emmanuelS21"
When I console log updateProfile after submitting updated profile data, I am only getting the last input I entered in my form (ie. If I enter last_name, I only see this in my console log while everything else in my object is empty)
CodePudding user response:
Each use of setProfileUser
is overwriting the entire object with a new object that contains only one property:
onChange={ e => setProfileUser({'email': e.target.value}) }
You can destructure the current state to build the complete new state:
onChange={ e => setProfileUser({ ...profileUser, 'email': e.target.value}) }
This is notably different from the older setState
used in class-based components. With setState
the framework would automatically perform partial updates for you. But with the setter function in useState
hooks, any update is complete as-is.
CodePudding user response:
when you set the state must add rest of value to new object with {...rest}
onChange={ e => setProfileUser({...profileUser,'username': e.target.value}) }