Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for async function in React component & Showing Spinner

Beginner here.

Trying to fetch some data from a server and display it in my react component once its fetched. However, I am having trouble integrating the async function into my react component.

import React, { useState } from "react";
import { request } from "graphql-request";

async function fetchData() {
  const endpoint = "https://localhost:3090/graphql"

  const query = `
    query getItems($id: ID) {
      item(id: $id) {
        title
      }
    }
  `;

  const variables = {
    id: "123123123"
  };

  const data = await request(endpoint, query, variables);
  // console.log(JSON.stringify(data, undefined, 2));

  return data;
}

const TestingGraphQL = () => {
  const data = fetchData().catch((error) => console.error(error));

  return (
    <div>
      {data.item.title}
    </div>
  );
};

export default TestingGraphQL;

I'd like to simply show a spinner or something while waiting, but I tried this & it seems because a promise is returned I cannot do this.

like image 616
Peter Goldhahn Avatar asked Oct 23 '25 23:10

Peter Goldhahn


1 Answers

Here you would need to use the useEffect hook to call the API. The data returned from the API, I am storing here in a state, as well as a loading state to indicate when the call is being made.

Follow along the comments added in between the code below -

CODE

import React, { useState, useEffect } from "react"; // importing useEffect here
import Layout from "@layouts/default";
import ContentContainer from "@components/ContentContainer";
import { request } from "graphql-request";

async function fetchData() {
   const endpoint = "https://localhost:3090/graphql"

   const query = `
     query getItems($id: ID) {
       item(id: $id) {
         title
       }
     }
   `;

   const variables = {
      id: "123123123"
   };

   const data = await request(endpoint, query, variables);
   // console.log(JSON.stringify(data, undefined, 2));

   return data;
}

const TestingGraphQL = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  
  // useEffect with an empty dependency array works the same way as componentDidMount
  useEffect(async () => {
     try {
       // set loading to true before calling API
       setLoading(true);
       const data = await fetchData();
       setData(data);
       // switch loading to false after fetch is complete
       setLoading(false);
     } catch (error) {
       // add error handling here
       setLoading(false);
       console.log(error);
     }
  }, []);

  // return a Spinner when loading is true
  if(loading) return (
    <span>Loading</span>
  );

  // data will be null when fetch call fails
  if (!data) return (
    <span>Data not available</span>
  );

  // when data is available, title is shown
  return (
    <Layout>
      {data.item.title}
    </Layout>
  );
};
like image 100
himayan Avatar answered Oct 25 '25 12:10

himayan