Jay Park
Jay Park

Reputation: 348

Why react keep re-rendering when I call setState() in axios?

1.I was trying to fetch the data from the database and then set the state to that data. I used axios to fetch the data and called setState() function inside of axios. I can set the state successfully but it keep re-rendering. I try to consle.log(state) to check the result but it keep re-remdring. 2. Here is the screen shot of the console.log() result enter image description here

Here is my code,

import axios from "axios";
import React, { useState }  from "react";
import reactDom from "react-dom";

import TableRow from "../TableRow";

export default function Table(props){

    const [state, setState] = useState();

    axios.get("/get/employee/list")
    .then(response => response.data)
    .then((data) => {
       setState(data)
    });

    console.log(state);

    return (
        <div>
                <table className="table table-hover">
  <thead>
    <tr>
      <th scope="col" width="100px">#</th>
      <th scope="col" width="100px">Name</th>
      <th scope="col" width="100px">Salary</th>
      <th scope="col" width="100px">Action</th>
    </tr>
  </thead>
  <tbody>
    {/* {sates.employees.map( function (x, i){
        return <TableRow key={i} data={x}/>
    })} */}
  </tbody>
</table>
        </div>
    )
}

Upvotes: 0

Views: 1908

Answers (3)

Shambhu Sahu
Shambhu Sahu

Reputation: 341

Whenever we make an API call in react component, usually we store the retrieved data in a state. A react component re-renders after any change in the current state. As soon as we store our retrieved data in the state our component will re-render and the API call will be triggered again. This cycle will continue, and we will be facing the issue of an infinite loop in our component. That is where useEffect() hook comes into play and can save the day for our re-rendering problem.

Pretty much anything you want to “do” in a React component other than return JSX (any sort of side effect), will go into a useEffect. (and you can have more than one useEffect per component, too)

import axios from "axios";
import React, { useState, useEffect }  from "react";
import reactDom from "react-dom";

import TableRow from "../TableRow";

export default function Table(props){

    const [state, setState] = useState();

    useEffect(() => {
        axios.get("/get/employee/list")
        .then(response => response.data)
        .then((data) => {
           setState(data)
        });
    },[])

    console.log(state);

    return (
        <div>
                <table className="table table-hover">
  <thead>
    <tr>
      <th scope="col" width="100px">#</th>
      <th scope="col" width="100px">Name</th>
      <th scope="col" width="100px">Salary</th>
      <th scope="col" width="100px">Action</th>
    </tr>
  </thead>
  <tbody>
    {/* {sates.employees.map( function (x, i){
        return <TableRow key={i} data={x}/>
    })} */}
  </tbody>
</table>
        </div>
    )
}

here I have add useEffect hook with the empty array which means that function inside the useEffect will only run once.

Upvotes: 1

Arash Ghazi
Arash Ghazi

Reputation: 991

each state update case run every code on body

import axios from "axios";
import React, { useState,useEffect }  from "react";
import reactDom from "react-dom";
import TableRow from "../TableRow";

export default function Table(props){

    const [state, setState] = useState();
useEffect(()=>{
    const fetchdata=async()=>{axios.get("/get/employee/list")
    .then(response => response.data)
    .then((data) => {
       setState(data)};
   if(!state)
      fetchdata();
    });
},[])
   

    return (
        <div>
                <table className="table table-hover">
  <thead>
    <tr>
      <th scope="col" width="100px">#</th>
      <th scope="col" width="100px">Name</th>
      <th scope="col" width="100px">Salary</th>
      <th scope="col" width="100px">Action</th>
    </tr>
  </thead>
  <tbody>
    {/* {sates.employees.map( function (x, i){
        return <TableRow key={i} data={x}/>
    })} */}
  </tbody>
</table>
        </div>
    )
}

Upvotes: 2

David Yappeter
David Yappeter

Reputation: 1612

wrap your axios inside useEffect that have [] dependencies so it will only run once on mount

import axios from "axios";
import React, { useState, useEffect }  from "react";
import reactDom from "react-dom";

import TableRow from "../TableRow";

export default function Table(props){

    const [state, setState] = useState();

    useEffect(() => {
        axios.get("/get/employee/list")
        .then(response => response.data)
        .then((data) => {
           setState(data)
        });
    },[])

    console.log(state);

    return (
        <div>
                <table className="table table-hover">
  <thead>
    <tr>
      <th scope="col" width="100px">#</th>
      <th scope="col" width="100px">Name</th>
      <th scope="col" width="100px">Salary</th>
      <th scope="col" width="100px">Action</th>
    </tr>
  </thead>
  <tbody>
    {/* {sates.employees.map( function (x, i){
        return <TableRow key={i} data={x}/>
    })} */}
  </tbody>
</table>
        </div>
    )
}

Upvotes: 2

Related Questions