skip to Main Content

I want to call an api and get some data in useEffect

const Input = () => {
    const data = useRef({})

    const fetchData = async () => {
        const res = await fetch('api here')
        const json = await res.json()
        return json.result
    }

    useEffect(() => {
        console.log("bbbbbbbbbbbbbbbbbbbbbbbb")
        fetchData().then(apiData => {
            data.current = apiData
          }) 
    }, [])

    return (
        <>
            {data &&
                <div className="page-container">
                    <Overview {...data.description}></Overview>
                    <Entries entries={data.entry}></Entries>
                </div>
            }
        </>
    )
}

export default Input;

But I didn’t get any data from it. data is still an empty object.

I noticed that react may render first and the fetch data, so I add a {data && …}, but it still doesn’t work.

When I look at the terminal, there’s no log "bbbbbbb", it seems that useEffect is not executed.

I also tried some other code like this

async function fetchData() {
            axios
              .get(url)
              .then((response) => {
                const json = response.data;
                data.current = json
              })
              .catch((error) => {
                console.log(error);
              });

But it doesnt work either.

Why this happened? How to do async api call in useEffect? Or there are some better ways to do api calls?

I also use useState rather than useRef, but not work either

I try to put the definition into the useEffect, but not work either

 useEffect(() => {
        const fetchData = async () => {
            const res = await fetch('some api here')
            const json = await res.json()
            return json.result
        }
        console.log("bbbbbbbbbbbbbbbbbbbbbbbb")
        fetchData().then(apiData => {
            setData(apiData)
          }) 
    }, [])

4

Answers


  1. I highly recommend https://tanstack.com/query/latest
    It gives you the tools to handle loading, data, and error states in a straightforward way. Then you can treat data returned, loading, and errors like stateful variables, which simplifies the whole data fetching process.

    Login or Signup to reply.
  2. Use usestate to store data

    const Input = () => {
       const [data, setData] = React.useState([])
    
        
    
        useEffect(() => {
            axios
          .get("/api/getData")
          .then((res) => {
            setData(res.data)
          })
        }, [])
    
        return (
            <>
                {data && data.length>0 &&
                    <div className="page-container">
                        <Overview {...data.description}></Overview>
                        <Entries entries={data.entry}></Entries>
                    </div>
                }
            </>
        )
    }
    
    export default Input;
    
    Login or Signup to reply.
  3. I think you have to modify something because when you call you api in useEffect its only render first time that’s why you did not gey the value after fetch the data.

    const Input = () => {
        const data = useRef({})
        const [data, setData] = React.useState([])
    
        const fetchData = async () => {
            const res = await fetch('api here')
            const json = await res.json()
            return json.result
        }
    
        useEffect(() => {
            fetchData().then(apiData => {
                setData(apiData);
              }) 
        }, [fetchData])
    
        return (
            <>
                {data &&
                    <div className="page-container">
                        <Overview {...data.description}></Overview>
                        <Entries entries={data.entry}></Entries>
                    </div>
                }
            </>
        )
    }
    
    export default Input;
    
    Login or Signup to reply.
  4. You need useState instead of useRef. You can know difference between useRef and useState in the new react documentation.

    This is a working example using useState:

    import { useEffect, useState } from "react";
    
    const App = () => {
      const [data, setData] = useState([]);
    
      const fetchData = async () => {
        const res = await fetch(
          "https://random-data-api.com/api/v2/users?size=2&is_xml=true"
        );
        const json = await res.json();
        return json;
      };
    
      useEffect(() => {
        console.log("bbbbbbbbbbbbbbbbbbbbbbbb");
        fetchData().then((apiData) => {
          setData(apiData);
        });
      }, []);
    
      return (
        <>
          {data?.length && (
            <div className="page-container">{JSON.stringify(data)}</div>
          )}
        </>
      );
    };
    
    export default App;
    
    

    You can find a sandbox here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search