I'm having an issue when it comes to rendering some data out in my React app. I have a page /users
that renders a list of users and clicking on a specific user routes the client to a page with more info on that user /users/:id
. That page has a component with user data inside of it and that data is being fetched from a local JSON file. The issue is that when I click on one of the users from the /users
page, the page for that specific user breaks. Console is telling me userData
is undefined.
I have attempted to render the specific user page once the data has been fetched but I don't think I'm doing it correctly. I have tried setting an isLoading
state with useState
as well as conditionally rendering the component based on the state of the data being fetched but I'm still not having much luck. Below is the User page and the UserInfo
component.
User page
function User() {
const [userData, setUserData] = useState([]);
const { id } = useParams();
const fetchData = async () => {
const response = await fetch(`../data/userData/${id}.json`);
const data = await response.json();
setUserData(data);
};
useEffect(() => {
fetchData;
}, []);
return (
<div>
{userData ? (
<UserInfo userData={userData} />
) : (
<>
<h1>Loading...</h1>
</>
)}
</div>
);
}
UserInfo component
function UserInfo({ userData }) {
return (
<div className='userInfo__details'>
<div className='userInfo__name'>
<h1>{userData[0].name}</h1>
</div>
</div>
);
}
The page is being rendered before the userData is being retrieved by the fetch request and that's causing the page to break. Ideally I'd like to have a loading spinner or something while the data is retrieved but anytime I've been able to having else
condition render to indicate the data is still being fetched, it just hangs there and never actually renders the page with the fetched data.
Any help is appreciated.
CodePudding user response:
[]
as your default state is will return as true which renders the UserInfo
component before time.
You can do this instead
return (
<div>
{!!userData.length ? (
<UserInfo userData={userData} />
) : (
<>
<h1>Loading...</h1>
</>
)}
</div>
);