Home > database >  useEffect not working when trying to fetch information
useEffect not working when trying to fetch information

Time:09-15

I´m trying to fetch user information and show it to the page but when I go to the page it is completely blank and with errors saying that cannot read properties that are null. So I put console.log when it is suppose to fetch and it never shows, which is why I realized that the function inside the useEffect is not being called and I really don't know why.


  function User() {

  const[userInfo, setUserInfo] = useState(null);
  const {user, checkAuth} = useContext(UserContext);
  const [redirect, setRedirect] = useState(false);
  const params = useParams();

  function logout() {
    axios.post('http://localhost:3030/logout', {}, {withCredentials: true})
      .then(() => {
        checkAuth().catch(() => setRedirect(true));
      });
  }

  useEffect(() => {
    function getUserInfo() {
        axios.get('http://localhost:3030/users/' params.id)
        .then(response => {
          setUserInfo(response.data);
          console.log('here'); //this never shows in the console

        });
    }
    getUserInfo();
  }, [params.id]);

  if (redirect) {
    return (<Navigate to={'/'} />);
  }
 
  return (
    <main>
    <Container>
        <ContainerHeader>
            <StyledHeader>Profile</StyledHeader>
            {!!userInfo && !!user && parseInt(params.id) === user.id && (
            <LinksRow>
            <EditLinkButton to={'/profile'}><FontAwesomeIcon icon={faEdit} />  Edit</EditLinkButton>
            <Button onClick={() => logout()}><FontAwesomeIcon icon={faArrowRight} />  Logout</Button>
            </LinksRow>
            )}
        </ContainerHeader>
        
        <Img src={ProfileImg} alt=""/>
        <Name>{userInfo.first_name} {userInfo.last_name}</Name>
        <Role>{userInfo.role}</Role>
        <Role>{userInfo.sector}</Role>
        <Labels><FontAwesomeIcon icon={faEnvelope}/> {userInfo.email}</Labels>
        <Labels> <FontAwesomeIcon icon={faLocationDot} /> {userInfo.location} </Labels>
        <Labels>
            <Links href={userInfo.link} target="_blank"> <FontAwesomeIcon icon={faExternalLink} /> {userInfo.link}</Links>
        </Labels>
        <Labels> <FontAwesomeIcon icon={faCoins} /> 100 CxCoins</Labels>
        <SecondHeader>Statistics</SecondHeader>
        <Labels> <FontAwesomeIcon icon={faComment} /> 100 comments</Labels>
        <Labels> <FontAwesomeIcon icon={faTicket} /> 100 tickets</Labels>
              
    </Container>
    </main>
    
  );
}

export default User 

Thank you!

CodePudding user response:

  1. The API maybe throwing an error, so you code never enters then block. You need to add a catch block and render some ui with the error data or redirect user elsewhere or show a toaster etc... If you want to show a ui, you can add an error state to your component

  2. Until the API fetching the data for you, your userInfo is null, so you cant access for eg. userInfo.first_name. The component throws a rendering error, hence the useEffect never has a chance to run which would run had the rendering was completed successfully. Follow below code where I wait for userInfo to have some data on it before I access any of it's keys

  3. You can alsoconsider adding a loading state to your Component

     function User() {      
       const[userInfo, setUserInfo] = useState(null);
       const {user, checkAuth} = useContext(UserContext);
       const [redirect, setRedirect] = useState(false);
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(false);
    
    
       const params = useParams();
    
       function logout() {
         axios.post('http://localhost:3030/logout', {}, {withCredentials: true})
           .then(() => {
             checkAuth().catch(() => setRedirect(true));
           });
       }
    
       useEffect(() => {
         function getUserInfo() {
    setIsLoading(true)       axios.get('http://localhost:3030/users/' params.id)
             .then(response => {
               setUserInfo(response.data);
               console.log('here'); //this never shows in the console
    
             })
     .catch(err=>setError(err?.message)) 
     .finally(() =>setIsLoading(false)) 
         }
         getUserInfo();
       }, [params.id]);
    
       if (redirect) {
         return (<Navigate to={'/'} />);
       }
     if (isLoading) {
         return (<Loader />);
       }
    
       return (
         <main>
         <Container>
             <ContainerHeader>
                 <StyledHeader>Profile</StyledHeader>
                 {!!userInfo && !!user && parseInt(params.id) === user.id && (
                 <LinksRow>
                 <EditLinkButton to={'/profile'}><FontAwesomeIcon icon={faEdit} />  Edit</EditLinkButton>
                 <Button onClick={() => logout()}><FontAwesomeIcon icon={faArrowRight} />  Logout</Button>
                 </LinksRow>
                 )}
             </ContainerHeader>
     {error && <Error error={error}/> 
    {!error &&  Object.keys(userInfo).length>0 && (  <>
             <Img src={ProfileImg} alt=""/>
             <Name>{userInfo.first_name} {userInfo.last_name}</Name>
             <Role>{userInfo.role}</Role>
             <Role>{userInfo.sector}</Role>
             <Labels><FontAwesomeIcon icon={faEnvelope}/> {userInfo.email}</Labels>
             <Labels> <FontAwesomeIcon icon={faLocationDot} /> {userInfo.location} </Labels>
             <Labels>
                 <Links href={userInfo.link} target="_blank"> <FontAwesomeIcon icon={faExternalLink} /> {userInfo.link}</Links>
             </Labels>
             <Labels> <FontAwesomeIcon icon={faCoins} /> 100 CxCoins</Labels>
             <SecondHeader>Statistics</SecondHeader>
             <Labels> <FontAwesomeIcon icon={faComment} /> 100 comments</Labels>
             <Labels> <FontAwesomeIcon icon={faTicket} /> 100 tickets</Labels>
    
    </>) 
    }               
         </Container>
         </main>
    
       );
     }
    
     export default User
    

CodePudding user response:

Move getUserInfo method to outside of the userEffect hook.Then it may be work.

  • Related