Home > Enterprise >  Issue with 1st render of async local JSON data
Issue with 1st render of async local JSON data

Time:12-15

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>
  );
  • Related