Marina
Marina

Reputation: 187

Default value in input field lost after click

So, i'm making this social network app and it has user profile. if user wants to update profile, eg. name, by opening modal EditUser, the old value of users name should be there, in input filed, and user needs to have opportunity to change/update that. I used 'defaultValue', and there is it, in input field, but if i don't change anything in that field, just click 'update', it will be lost. updated value is empty string then, and not the value that is showing in that field. how can i fix this?

Also interested how to set as default user image. so, user has profile image, and on update if user changes only name, not the picture or something else, everything else should be the same, but photo is also like input text field lost.

here is what i tried: MyProfile.tsx

import React, { useState, useEffect, useContext } from 'react'
import './myprofile.css'
import Axios from 'axios'
import SinglePost from '../single_post/SinglePost'
import { AppContext } from '../context/AppContext'
import UpdateProfile from '../modals/UpdateProfile'

function MyProfile() {

    const [userInfo, setUserInfo] = useState({
        firstName: '',
        lastName: '',
        userBio: 'Write something about yourself.',
        userPhoto: ''
    })
    const [isEditOpen, setIsEditOpen] = useState(false)

    const { userID, setUserID } = useContext(AppContext)

    // open modal on click 'edit'
    const editUser = () => {
        setIsEditOpen(true)
    }

    // get user data
    const storedToken = localStorage.getItem('token')

    useEffect(() => {
        const config = {
            headers: { "x-auth-token": `${storedToken}` }
        }
        Axios
            .get('/api/auth/user', config)
            .then(res => {
                console.log('response', res)
                const user = res.data.user
                setUserID(user._id)
                setUserInfo({
                    firstName: user.first_name,
                    lastName: user.last_name,
                    userBio: user.user_bio,
                    userPhoto: user.profile_image
                })
            })
            .catch(err => console.log(err))
    }, [])


    return (
        <div className="profile-container">
            <button className="btn-edit" onClick={editUser}>
                <i className="fa fa-edit"></i>
            </button>
            <div className="user-info">
                <div className="img-circular">
                    <img className="user-profile-img2" src={userInfo.userPhoto}></img>
                </div>
                <p className="user-name">{userInfo.firstName} {userInfo.lastName}</p>
                <p className="about-user">{userInfo.userBio}</p>
            </div>
            <div className="user-posts">
                <p className="my-posts-title">My Posts</p>
            </div>
            {isEditOpen && <UpdateProfile
                userID={userID}
                setIsEditOpen={setIsEditOpen}
                isEditOpen={isEditOpen}
                setUserInfo={setUserInfo}
                userInfo={userInfo}
            />}
        </div>
    )
}

export default MyProfile

UpdateProfile.tsx

import React, { useState, useRef, useEffect } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter, Button, FormGroup, Label, Input } from 'reactstrap'
import Axios from 'axios'
import '../user_profile/myprofile.css'

function UpdateProfile(props: any) {

    const [firstNameUpdated, setFirstNameUpdated] = useState('')
    const [lastNameUpdated, setLastNameUpdated] = useState('')
    const [userBioUpdated, setUserBioUpdated] = useState('')

    const inputNameRef = useRef<HTMLInputElement | any>(null)

    useEffect(() => {
        console.log(inputNameRef.current, props.userInfo.firstName)
        inputNameRef.current && (inputNameRef.current.value = props.userInfo.firstName)
    }, [])

    // upload image
    const [file, setFile] = useState('')
    const [uploaded, setUploaded] = useState('')

    const handleImageUpload = (e: any) => {
        e.preventDefault();
        setFile(e.target.files[0])
    };

    const onClickHandler = (e: any) => {
        const formData = new FormData()
        formData.append('fileImage', file)

        Axios.post("/api/image", formData, {})
            .then(res => {
                //console.log(`UPLOADED: http://localhost:5000/${res.data.fileImage}`)
                setUploaded(`http://localhost:5000/${res.data.fileImage}`)
            })
            .catch(err => console.log(err))
    }

    // update user
    const updateUser = (e: any) => {
        e.preventDefault()

        props.setIsEditOpen(false)

        const formData = new FormData()

        formData.append('fileImage', file)
        formData.append('first_name', firstNameUpdated)
        formData.append('last_name', lastNameUpdated)
        formData.append('user_bio', userBioUpdated)

        const config: any = { header: { "Content-Type": "multipart/form-data" } }

        Axios
            .put(`/api/users/${props.userID}`, formData, config)
            .then(res => {
                const user = res.data
                props.setUserInfo({
                    firstName: user.first_name,
                    lastName: user.last_name,
                    userBio: user.user_bio,
                    userPhoto: user.profile_image
                })
            })
            .catch(err => console.log(err))
    }

    return (
        <div>
            {props.isEditOpen &&
                <Modal isOpen={props.isEditOpen} toggle={() => props.setIsEditOpen(!props.isEditOpen)} backdrop="static">
                    <ModalHeader>Update your profile</ModalHeader>
                    <ModalBody>
                        <FormGroup>
                            <Label>Profile Image</Label>
                            <Input type="file" name="fileImage" onChange={handleImageUpload}></Input>
                        </FormGroup>
                        <Button onClick={onClickHandler} className="btn-upload-img">Upload file</Button>
                        <div className="inline">
                            {uploaded ? <img src={uploaded} style={{ width: "100px" }}></img> : <img  src={props.userInfo.userPhoto} style={{ width: "100px" }}></img>}
                        </div>
                        <FormGroup>
                            <Label>First Name</Label>
                            <Input type="text" onChange={(e: any) => setFirstNameUpdated(e.target.value)} defaultValue={props.userInfo.firstName}></Input>
                        </FormGroup>
                        <FormGroup>
                            <Label>Last Name</Label>
                            <input type="text" onChange={(e: any) => setLastNameUpdated(e.target.value)} defaultValue={props.userInfo.lastName} ></input>
                        </FormGroup>
                        <FormGroup>
                            <Label>About me</Label>
                            <Input type="text" onChange={(e: any) => setUserBioUpdated(e.target.value)} defaultValue={props.userInfo.userBio}></Input>
                        </FormGroup>
                    </ModalBody>
                    <ModalFooter>
                        <Button color="success" onClick={updateUser} className="btn-update">Update</Button>
                        <Button color="danger" onClick={() => props.setIsEditOpen(false)}>Cancel</Button>
                    </ModalFooter>
                </Modal>}
        </div>
    )
}

export default UpdateProfile

I'm just trying to get the old value in input field (which i did), and user can choose if wants to change that or not. if not, old value should stay in updated profile, but in my case, on click 'update' it is lost in user profile.

Upvotes: 1

Views: 417

Answers (1)

Raghvender Kataria
Raghvender Kataria

Reputation: 1485

In UpdateProfile, you should initialise the states with the value you got in props and later they could change.

const [firstNameUpdated, setFirstNameUpdated] = useState(props.userInfo.firstName)
    const [lastNameUpdated, setLastNameUpdated] = useState(props.userInfo.lastName)
    const [userBioUpdated, setUserBioUpdated] = useState(props.userInfo.userBio)

Initialising the state could solve all your problem.

Upvotes: 1

Related Questions