Home > other >  React useEffect with axios
React useEffect with axios

Time:05-24

Below is a snippet of code to fetch data from url by axios,

import React, { useState, setEffect, useEffect } from 'react';
import axios from "axios";
import LoadingPage from "./LoadingPage";
import Posts from "./Posts";

const url = "https://api-post*****";

function App() {
    const [posts, setPosts] = useState([]);
    
    const fetchPost = async() => {
        try {
            const response = await axios(url);
            return response.data;
        } catch (error) {
            console.error(error);
        }
    };
    
    let data = fetchPost();
    setPosts(data);
    
    return (
        <main>
            <div className="title">
                <h2> Users Posts </h2>
                {posts.length
                ? <Posts posts={posts} />
                : <Loading posts={posts} />
                }
            </div>
        </main>
    );
}

export default App;

However, it got the error of

uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite

Question 1: How could this be of too many re-render, there is no loop or something?

To solve this bug, we can use below changes:

  const [posts, setPosts] = useState([]);

  const fetchPost = async () => {
    try {
      const response = await axios(url);
      setPosts(response.data);
    } catch (err) {
      console.error(err);
    }
  };

  useEffect(()=> {
    fetchPost();
  }, [posts])

Question 2: how the useEffect work to avoid too many calls?

Question 3: I always treat react hooks under hood as web socket communications, etc. If that is the case?

CodePudding user response:

Please first check your state like this.

useEffect(()=> {
    fetchPost();
}, [posts]);

CodePudding user response:

When you call setPosts the component will render again, and fetch the data again, at which point you set state with the data forcing a new render which fetches the data...etc.

By using useEffect you can fetch the data, and set state once when the component is first rendered using an empty dependency array.

useEffect(() => {
  // Fetch the data
  setposts(data);
}, []);

You probably don't want to watch for posts in this useEffect (you can have many) like you're doing in your updated example because you may run into the same issue.

CodePudding user response:

I will only answer number one.

Caveat: the answer is a bit long.

I really hope it will help you to understand a topic that took me a long time to grasp.

Answer one:

To answer this question we should ask our selves two things, a) what is a side effect? and b) how the life cycle of components works?

so, we know that React functional component are pure functions and they should stay that way, you can pass props as parameters and the function will do stuff and return JSX, so far so good.

and for the second part we cannot control React virtual DOM, so the component will render many times during it's lifecycle, so imagine that the virtual DOM decided to check the code and compare between the virtual DOM and the real DOM and in order to do that he will have to check and "run" the code that resides inside that specific component.

the virtual DOM will run the API call, he will find a different result which will cause a new render to that specific component and this process will go on and on as an infinite loop.

when you are using usEffect you can control when this API call will take place and useEffect under the hood makes sure that the this API call ran only one your specific change take place and not the virtual DOM V.S real DOM change.

to summarize, useEffect basically helps you to control the LifeCycle of the component

  • Related