Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Too slow data fetching in React, leading to annot read properties of undefined error

I have a problem with data displaying. Probably the JSX content is rendering too fast before data is actually fetched from API and that causing the following:

Uncaught TypeError: Cannot read properties of undefined (reading ‘name’)

I checked with console.log; sometimes it’s fetching, sometimes not. Also, when I comment out this {concerts[1].name}, then data is loaded and populated. However, when I run it like in the example below, data is not populating, and I am getting errors.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import React from "react";
import { useEffect, useState } from "react";
import axios from "axios";

export const ConcertNewest = () => {
  const [concerts, setConcerts] = useState([]);

  useEffect(() => {
    const loadConcerts = async () => {
      const response = await axios.get("/data/concerts");

      setConcerts(response.data);
    };
    loadConcerts();
  }, []);

  console.log("concerts: " + concerts.length);
  return (
    <show>
      <h1>Newest concerts </h1>
      <div>
        <div className="card">
          <img src="" style={{ width: 100 }} />
          <div className="card-text">
            <h4> {concerts[1].name}</h4>
          </div>
        </div>
      </div>
    </show>
  );
};

>Solution :

The code inside useEffect runs after the JSX is rendered. That’s by design. So you are ending up with concerts[1].name while concerts is still empty.

A common way to tackle this is to show some loading indicator while the data is being fetched, like so, for example:

import React from "react";
import { useEffect, useState } from "react";
import axios from "axios";

export const ConcertNewest = () => {
  const [concerts, setConcerts] = useState([]);

  useEffect(() => {
    const loadConcerts = async () => {
      const response = await axios.get("/data/concerts");

      setConcerts(response.data);
    };
    loadConcerts();
  }, []);

  if (!concerts.length) {
    return <p>Loading...</p>;
  }
  return (
    <show>
      <h1>Newest concerts </h1>
      <div>
        <div className="card">
          <img src="" style={{ width: 100 }} />
          <div className="card-text">
            <h4> {concerts[1].name}</h4>
          </div>
        </div>
      </div>
    </show>
  );
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading