0

I have this wrapper component which renders out a DepartmentSection for each of the key-value pairs in DEPARTMENTS. Below is the simplified code:

import React from 'react';
import DepartmentSection from './DepartmentSection';

const AllDepartmentsWrapper = () => {

  export const DEPARTMENTS = {
    Math: 1,
    Science: 2,
    //... other departments
  };

  return Object.keys(DEPARTMENTS).map(deptName => {
    return (
      <DepartmentSection
        key={deptName}
        name={deptName}
      />
    );
  });
};

export default AllDepartmentsWrapper;

Inside of each DepartmentSection, I am making an api call that fetches some data. Once the data for that section loads, the component will display the data in a graph. Here is a simplified version:

const DepartmentSection = ({ name }) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchDepartmentData(name).then( // fetch the data
      resp => {
        setLoading(false);
        setData(resp);
      }
    );
  }, [name]);

  return (
    <div>
      <h1>{name}</h1>
      {loading ? 'loading...' : <DataGraph data={data} />}
    </div>
  );
};

The way that this currently functions, each of the DepartmentSections is mounted and the api request is immediately sent. Because of this, the department charts seem to randomly appear as the data is fetched.

What I want is for the data to be fetched based on the order that the departments are listed in the DEPARTMENTS constant. So for instance, in this case the math data would be fetched and then graphed and then the science data would be fetched and graphed. I'm thinking of it as a sort of automatic lazy-load. I still want to pull the data for all departments but I want to do it top-to-bottom.

Does anyone have thoughts on how to accomplish this?

6
  • Even if you kicked off the network requests in order, you can't guarantee how long they'll take, so the second request could finish before the first, etc. If you really want to do this you might need to juggle some "latest index to load" state variable, and use that to reveal elements in order, once all n records have loaded up to that index. Or you could load them all at once in the parent component with Promise.all(). Or you could use a true lazy loading scroll solution that doesn't mount a component until it's on screen. Or move to loading in batches instead and show one batch at a time. Commented Aug 30, 2023 at 21:59
  • Does this answer your question? Fetch in loop, keep result order Commented Aug 30, 2023 at 22:06
  • @HereticMonkey no that does not answer my question because it is sending all of the requests at once. What I'm looking to do is send the first request and then only send the second once the data for the first has been received Commented Aug 31, 2023 at 14:40
  • @AndyRay I think your idea about loading in batches is what I'm after, I just want to load with a batch size of 1. I do not want to use Promise.all() because I still have to wait for all of the data before displaying. And I do not want to use a classic lazy loader because the elements need to load before they are on screen Commented Aug 31, 2023 at 14:42
  • You may wish to edit your question to make that more clear. There's nothing indicating that the fetches need to be made in order, only that the results need to be shown in the order in which they were added to the request. Commented Aug 31, 2023 at 16:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.