Home > other >  Object/state only updating one property on button submission
Object/state only updating one property on button submission

Time:03-29

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}) }
  • Related