using useState async makes webapp render unlimited times

Here I have a useState for posts of my blog webapp. I am getting the posts from the mongoose back end which works fine. But the second I set the posts variable I get an infinite loop of rerendering.

Here is the app.jsx:

import React, {useState} from 'react';
import './App.css';
import Nav from './Navbar/NavBar.jsx';
import Content from "./content/Content"
import { getPosts } from "./api/post";

function App() {

    const idList = ["631a58c165b3a10ac71497e1", "631a58fa65b3a10ac71497e3"];

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

    setPosts(async() => await getPosts(idList));

  return (

export default App;

Here is the axios part:

import axios from "axios";

const getPost = (id) => {
    new Promise((resolve, reject) => {
        const url = "/posts/" + id
            .then(response => {
                if (response.status === 200){
                    console.log("Succesfull call");
                else if(response.status === 404){
            .catch(err => {
                console.log("Failed call");

const getPosts = async (idList) => {
    var result = []
    for(const id in idList){
            let post = await getPost(idList[id]);
    if (result.length === 0) throw {message: "No posts"};
    else return result;


export {getPosts};

How can I run setPosts async so that the site wont refresh infinitely?

>Solution :

You cannot pass a function returning a promise into the state setter. It must return the new state value directly.

You’ll want to use an effect hook instead

useEffect(() => {
}, []); // empty dependency array means run once on mount

Given idList appears constant, you should define it outside your component. Otherwise you’ll need to work around its use as a dependency in the effect hook.

Your getPosts function falls prey to the explicit promise construction anti-pattern. Since Axios already returns a promise, you don’t need to make a new one.

You can also use Promise.allSettled() to make your requests in parallel.

const getPost = async (id) => (await axios.get(`/posts/${id}`)).data;

const getPosts = async (idList) => {
  const results = (await Promise.allSettled(
    .filter(({ status }) => status === "fulfilled")
    .map(({ value }) => value);

  if (results.length === 0) {
    throw new Error("No posts");
  return results;

Leave a Reply