1

I am new with react hooks, i'm trying to get info from an API but when i do the request i get 2 responses first an empty array and then the data of the API, why am i getting that empty array! , this is my first question, i'm sorry. Thanks for helping me !

import {useState, useEffect} from 'react';

const getSlides = (API) => {

    const[data,setData] = useState([]);

    const getData = () =>
    fetch(`${API}`)
        .then((res) => res.json())
    
    useEffect(() => {
        getData().then((data) => setData(data))
    },[])




    return data
}

export default getSlides;

hook code

1
  • You're not printing the API response, you're printing the state value. Which is initially an empty array, THEN gets populated with the API response data. Commented Oct 30, 2020 at 2:41

4 Answers 4

3

The useEffect() hook runs after the first render. Since you've initialized the data state with an empty array, the first render returns an empty array.

If you're component depends on data to render, you can always conditionally return null until your data is loaded.

Also, I recommend using an async function for api requests, it allows you to use the await keyword which makes your code easier to read. The only caveat, is that you cannot pass an async function to useEffect, instead define an async function inside your hook, and then call it.

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

const API = "https://example.com/data";

const GetSlides = (props) => {
  const [data, setData] = useState();

  useEffect(() => {
    async function getData() {
      const request = fetch(API);
      const response = await request;
      const parsed = await response.json();
      setData(parsed);
    }

    getData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  if (data === undefined) {
    return null;
  }

  return <>data</>;
};

export default GetSlides;

Of course, you can still use Promise chaining if you desire.

  useEffect(() => {
    async function getData() {
      await fetch(API)
        .then((res) => res.json())
        .then((data) => setData(data));
    }
    getData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
Sign up to request clarification or add additional context in comments.

Comments

1
<GetSlides api="https://yay.com" />

react components need to be title case

import React, { useState, useEffect } from 'react'

const GetSlides = ({ api }) => {
  const [data, setData] = useState(null)

  const getData = async () =>
    await fetch(`${api}`)
      .then((res) => res.json())
      .then((data) => setData(data))

  useEffect(() => {
    getData()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  console.log(data)

  return <div>slides</div>
}

export default GetSlides

Comments

0

The effect callback function is called after the render of your component. (Just like componentDidMount) So during the first render phase, the data state has not been set yet.

Comments

0

You initialize your data with and empty array here:

const[data,setData] = useState([] <- empty array);

useEffect runs after your component is mounted, and then calls the API, that it might take a few seconds or minutes to retrieve the data, but you return the data right away before knowing if the API finished its call.

If you want to return the data after it has been retrieved from the API, you should declare and async method

const getSlides = async (API) => {
 try {
  const res = await fetch(API);
  const data = await res.json();

   return data;
  } catch (e) {
    throw new Error(e);
  }
}

Note that it is not necessary hooks for this function

Comments

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.