Home > Mobile >  React undefined property when send to child component
React undefined property when send to child component

Time:09-03

I want to send the login user object to the profile page to edit and upload an image but It ends with the error "ProfileImage.jsx:25 Uncaught TypeError: Cannot read properties of undefined (reading 'photoUrl')" Here is my Parent Code :

import React from 'react';
import { useState } from 'react';
import {getCurrentUser, logout} from '../../services/authService'

import {useNavigate} from "react-router-dom";
import UpdateForm from '../../components/UpdateForm';
import ProfileImage from '../../components/ProfileImage';

import './Profile.css'
import { useEffect } from 'react';


const ProfilePage = () => {
    
    const navigate = useNavigate();
    const [user,setUser] = useState();
    
    useEffect(()=>{
        const getUser = async () => {
            const {data} = await getCurrentUser();
            setUser(data);
        }
        getUser()
    },[])
    
    const handelSignOut =()=>{
        logout();
        setUser('');
        navigate('/sign')
    }
    
    return (
        <div className='prof-con'>
            <div className='prof-flex-wraper'>
               <div className='prof-second-row'>
                    <div className='prof-text'>
                        <ProfileImage user={user}/>
                    </div>
                    <div className='prof-form'>
                        <UpdateForm user={user}/> 
                    </div>
                </div>
            </div>

        </div>
    );
}
export default ProfilePage;

and here is the profile Child component

import React from 'react';
import { useState } from 'react';
import {updatePhoto} from '../services/authService'
import DefaultUserPic from "../images/team-male.jpg";

function ProfileImage({user}) {
    const [previewSrc,setPreviewSrc] = useState(null)
    const [photoSrc,setPhotoSrc] = useState(null)
    
    
    const handelPreview = (e)=>{
        setPreviewSrc(URL.createObjectURL(e.target.files[0]))
        setPhotoSrc(e.target.files[0]);
    }
    
    const handelUpload = ()=>{
       const formData = new FormData();
       console.log(photoSrc)
       formData.append("file", photoSrc);
       updatePhoto(formData);
    }
    
    //console.log(user.photoUrl)
    console.log(user)
    
 
    // if(previewSrc){
    //     var imagestr=previewSrc;
    //     console.log(imagestr)
    //     // imagestr = imagestr.replace("public/", "");
    //     // var profilePic="http://localhost:3001/" imagestr;
    // }else{
    //      var profilePic='DefaultUserPic';
    // }
    
 
    return (
        <div className='profWraper'>
            <input type="file" name="fileToUpload" id="fileToUpload" onChange={handelPreview}/>
            <img className='profPhoto' src={previewSrc} alt="No-Image" />
            {photoSrc && <button className='uploadBtn' onClick={handelUpload}>Upload</button>}
            
        </div>
    );
}

export default ProfileImage;

if I log the user itself I get it in the console but if I try to get any property get an error undefined.

CodePudding user response:

Changing

<ProfileImage user={user}/>

to

{user && <ProfileImage user={user}/>}

might help

CodePudding user response:

You are asynchronously assigning user within the useEffect of ProfileImage. That means user will be undefined until that asynchronously logic resolves. You either have to check to see if user is defined before accessing its properties, or you need to assign user some kind of default properties in your useState.

CodePudding user response:

The error message suggests that user is undefined. Considering that the parent performs an async operation to get the user, I'd say the problem is that the child tries to access the user before the async operation is resolved.

Solution, add a guard against undefined user in the child:

if (user === undefined) return
  • Related