I just ran into this problem and couldn't find any resources about my case. I'm building a React app that uses the Spotify API and want to execute a function that populates a local useState object with an "ArtistInformation" array (a js object from the API endpoint).
This code example iterates through the artist id array and should only execute the Api function "spotiApi.getArtistInfo(id)" once.
When run like this:
const getArtistInformation = () => { console.log("sp ids",spotifyArtistIds) Promise.all(spotifyArtistIds.map(id => { return spotiApi.getArtistInfo(id) })).then(respList => { // setArtistInfo(respList) console.log("artistInfo", artistInfo)}) }
Code snippet runs fine and stops execution
But when "setArtistInfo" useState is called, the loop continues to execute infinitely
const getArtistInformation = () => { console.log("sp ids",spotifyArtistIds) Promise.all(spotifyArtistIds.map(id => { return spotiApi.getArtistInfo(id) })).then(respList => { setArtistInfo(respList) console.log("artistInfo", artistInfo)}) }
The following is the entire component for reference:
import { Box } from "@mui/material"; import React, { useEffect, useState } from "react"; import { useSelector } from "react-redux"; import SpotifyApi from "../../api/SpotifyApi"; export const DashboardView = () => { const spotifyArtistIds = useSelector(state => state.member.spotifyArtistIds) const [artistInfo, setArtistInfo] = useState([]) const [showId, setShowId] = useState(spotifyArtistIds[0]) const spotiApi = new SpotifyApi(); const getArtistInformation = () => { console.log("sp ids",spotifyArtistIds) Promise.all(spotifyArtistIds.map(id => { return spotiApi.getArtistInfo(id) })).then(respList => { // setArtistInfo(respList) console.log("artistInfo", artistInfo)}) } const getThisArtistInfo = () => { console.log("art", artistInfo) return artistInfo.filter(info => info.data.id === showId)[0].data } useEffect(() => { getArtistInformation() }) return ( <Box> <h2>{getThisArtistInfo()?.name}'s Dashboard</h2> </Box>) }
Thanks for any help in advance and hope we can figure this out!
The loop will not execute endlessly, and the component will re-render endlessly. This causes a re-render:
This is executed on every render :
So each rendering will get the artist information, which will trigger a re-render, which will get the artist information, which will trigger a re-render, etc.
If the intent is to get artist information only on the first render, include an empty dependencies array: