skip to Main Content

I have a question about how to manage state in a React apps. What I have been accustomed to doing is something like this – some of this is pseudocode:

Home.js

const LOADING_TIMEOUT_CONSTANT = 1000
import React, { useState, useEffect } from "react";

export default function Home(){
  const [loaded, isLoaded] = useState(false);
  const results = getData();

  useEffect(()=> {
    // wait for results to fetch from server
    setTimeout(() => {
      isLoaded(true)
    }, LOADING_TIMEOUT_CONSTANT)
  }, [])

  return (
    <div>
      {!loaded ? <p>Loading ....</p> : <p>Homepage Content Here</p>}
    </div>
  )
}

This however, seems a bit clunky to me and I’m not clear on best practices. Is this the standard, or are there other ways to manage this type of conditional display based on loading states or just any asynchronous fetching?

Thanks!

Tried searching stackoverflow, looking up youtube videos, searching reddit, etc. but I’m more looking into what the overall standard is for react developers.

4

Answers


  1. I guess there isn’t a best practice to things in developers world, but instead of relying on a setTimeout(), I tend to manually assign states using try..catch..finally like:

    const [loading, setLoading] = useState(true);
    
    useEffect(() => {
      const getSomething = async() => {
        setLoading(true);
        try {
          //fetch code
        } catch (error) {
          //error handler
        } finally {
          setLoading(false);
        }
      };
    
      getSomething();
    }, []);
    Login or Signup to reply.
  2. This is other ways to manage this type of condition

    if(!loaded){
    return (
        <div>
          <p>Loading ....</p>
        </div>
      )
    }
    return (
        <div>
          <p>Homepage Content Here</p>
        </div>
      )
    
    Login or Signup to reply.
  3. One of the nice and easy-to-learn conventions you could follow is using React Query with Axios for asynchronous data fetching:

    For example (more details on https://www.copycat.dev/blog/react-query/):

    import React from "react";
    import axios from "axios";
    import { useQuery } from "react-query";
    
    export default function Repositories() {
      const { isLoading, isError, data, error, refetch } = useQuery(["repo"], () =>
        axios
          .get("https://api.github.com/users/eunit99/repos")
          .then((res) => res.data)
      );
     
      if (isLoading) return "Loading...";
      if (error) return "An error has occurred: " + error.message;
      return (
        <>
          {data}
        </>
      )
    };
    

    React Query basically gives you the useQuery hook that returns a handful of objects such as isLoading, data, error, refetch, etc. These objects will help you check different states and render output accordingly.

    Axios helps you to fetch/send data using promises.

    To learn about more advanced usage of these tools, check out their docs:

    https://github.com/axios/axios

    https://tanstack.com/query/latest

    Login or Signup to reply.
  4. You need to make some changes so that loading state can be updated when getData request completes.

    import React, { useState, useEffect } from "react";
    
    export default function Home(){
      const [loaded, setLoaded] = useState(false);
      const [results, setResults] = useState(null);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            // Assuming getData is an async function
            const data = await getData();
            setResults(data); // Store the fetched data in state
            setLoaded(true); // Update loading state after data is fetched
          } catch (error) {
            console.error("Error fetching data: ", error);
            setLoaded(true); // Ensure loading state is updated even if fetching fails
          }
        };
    
        fetchData();
      }, []); // Empty dependency array means this effect runs once on mount
    
      return (
        <div>
          {!loaded ? <p>Loading ....</p> : <p>Homepage Content Here</p>}
        </div>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search