Maison  >  Questions et réponses  >  le corps du texte

La boucle de carte React.js avec async Promise est infinie si l'environnement Promise.all.then(response ... ) attribue une valeur de réponse

Je viens de rencontrer ce problème et je n'ai trouvé aucune ressource concernant mon cas. Je construis une application React qui utilise l'API Spotify et je souhaite exécuter une fonction qui remplit un objet useState local avec un tableau "ArtistInformation" (un objet js du point de terminaison de l'API).

Cet exemple de code parcourt le tableau d'identifiant d'artiste et ne doit exécuter la fonction API "spotiApi.getArtistInfo(id)" qu'une seule fois.

Quand on court comme ça :

const getArtistInformation = () => {
    console.log("sp ids",spotifyArtistIds)
    Promise.all(spotifyArtistIds.map(id => {
      return spotiApi.getArtistInfo(id)
    })).then(respList => {
      // setArtistInfo(respList)
      console.log("artistInfo", artistInfo)})
  }

L'extrait de code fonctionne correctement et cesse de s'exécuter

Mais lorsque "setArtistInfo" useState est appelé, la boucle continue de s'exécuter à l'infini

const getArtistInformation = () => {
    console.log("sp ids",spotifyArtistIds)
    Promise.all(spotifyArtistIds.map(id => {
      return spotiApi.getArtistInfo(id)
    })).then(respList => {
      setArtistInfo(respList)
      console.log("artistInfo", artistInfo)})
  }

Voici le composant complet pour référence :

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>)
}

Merci d'avance pour toute aide et j'espère que nous pourrons comprendre cela !

P粉895187266P粉895187266422 Il y a quelques jours431

répondre à tous(1)je répondrai

  • P粉819533564

    P粉8195335642023-09-15 12:18:13

    La boucle ne s'exécutera pas à l'infini, le composant sera restitué à l'infini. Cela provoque un nouveau rendu :

    setArtistInfo(respList);

    Ceci est exécuté à chaque rendu  :

    useEffect(() => {
      getArtistInformation();
    });

    Ainsi, chaque rendu obtient les informations sur l'artiste, ce qui déclenche un nouveau rendu, qui obtient les informations sur l'artiste, ce qui déclenche un nouveau rendu, etc

    Si l'intention est d'obtenir des informations sur l'artiste uniquement sur le premier rendu, incluez un tableau de dépendances vide :

    useEffect(() => {
      getArtistInformation();
    }, []); // <-- here

    répondre
    0
  • Annulerrépondre