在呈现组件之前未获取数据

时间:2021-06-10 23:54:58

标签: javascript reactjs

我能够使用 react + springboot + postgres 构建登录功能。登录后,当 JWT 存储在 localstore 中时,我的应用程序重定向到我正在为其呈现 /profile 组件的 <Profile /> 页面,如下所示:

Profile.js

import React, { useState, useEffect } from "react";
import UserDataService from '../services/user.services'

export default function ProfileModule(props) {

    const [userDetails, setUserDetails] = useState(undefined);

    const retrieveUserDetails = () => {
        console.log('Retrieving data')
        UserDataService.getUserDetails()
          .then(response => {
            setUserDetails(response.data);
            console.log(response.data);
          })
          .catch(e => {
            console.log(e);
          });
      };

    useEffect(() => {
        retrieveUserDetails();
    }, []);
      
    return (
        <div style={{paddingLeft:50, marginTop: -20}}>
            <h1> Welcome {userDetails.firstName + " " + userDetails.lastName} + "," </h1>
            <br />
            User Name: {userDetails.userName}
            <br />
            Phone Number: {userDetails.phone}
            <br />
            Email: {userDetails.email}
        </div> 
    )
}

但是在渲染上面的组件时,我得到了

TypeError: Cannot read property 'firstName' of undefined
ProfileModule
../client/src/components/Profile.js:26
  23 |   
  24 | return (
  25 |     <div style={{paddingLeft:50, marginTop: -20}}>
> 26 |         <h1> Welcome {userDetails.firstName + " " + userDetails.lastName} + "," </h1>
     | ^  27 |         <br />
  28 |         User Name: {userDetails.userName}
  29 |         <br />

不知何故,userDetails 没有被填充。我在 Chrome 中调试了 retrieveUserDetailsuseEffect 以及 user.services.getUserDetails() 上的断点。但是没有断点被击中。此外,这些 console.log() 都不可见。我缺少什么?

user.services.js

import axios from "axios";
import authHeader from "./auth-header";

const API_URL = "http://localhost:8080/api/test/";

const getUserDetails = () => {
    const user = JSON.parse(localStorage.getItem('user'));
    return axios.get(API_URL + "userdetails/" + user.username, { headers: authHeader() } );
}

export default {
  getUserDetails,
};

(我在 Postman 中测试了端点 http://localhost:8080/api/test/userdetails/username,它正在检索详细信息。)

1 个答案:

答案 0 :(得分:0)

您的 ProfileModule 在被调用时立即渲染 - 它不会等待效果回调完成后再渲染。

将渲染的 JSX 更改为仅在收到数据后才渲染。

return !userDetails ? null : (
    <div style={{paddingLeft:50, marginTop: -20}}>
        <h1> Welcome {userDetails.firstName + " " + userDetails.lastName} + "," </h1>
        <br />
        User Name: {userDetails.userName}
        <br />
        Phone Number: {userDetails.phone}
        <br />
        Email: {userDetails.email}
    </div> 
)

你也可以简化

useEffect(() => {
    retrieveUserDetails();
}, []);

useEffect(retrieveUserDetails)