La boucle de carte React.js avec async Promise est infinie si l'environnement Promise.all.then(response ... ) attribue une valeur de réponse
P粉895187266
P粉895187266 2023-09-14 16:02:55
0
1
457

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粉895187266
P粉895187266

répondre à tous(1)
P粉819533564

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
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal