首頁  >  問答  >  主體

帶有非同步 Promise 的 React.js 映射循環是無限的,如果周圍的 Promise.all.then(response ... ) 分配響應值

我剛剛遇到這個問題,找不到任何關於我的案例的資源。 我正在建立一個使用 Spotify API 的 React 應用程序,並想要執行一個函數,該函數用“ArtistInformation”數組(一個來自 API 端點的 js 物件)填充本地 useState 物件。

此程式碼範例循環存取藝術家 id 數組,並且應該只執行 Api 函數「spotiApi.getArtistInfo(id)」一次。

像這樣運行時:

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

程式碼片段運作良好並停止執行

但是當呼叫「setArtistInfo」useState 時,循環會繼續無限執行

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

以下是整個元件供參考:

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

感謝您提前提供的任何幫助,希望我們能解決這個問題!

P粉895187266P粉895187266373 天前386

全部回覆(1)我來回復

  • P粉819533564

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

    循環不會無止盡地執行,元件會無止盡地重新渲染。這會導致重新渲染:

    setArtistInfo(respList);

    在每次渲染時執行

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

    因此每次渲染都會獲取藝術家信息,從而觸發重新渲染,從而獲取藝術家信息,從而觸發重新渲染,等等

    如果目的是僅在第一次渲染上獲取藝術家信息,請包含一個空的依賴項數組:

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

    回覆
    0
  • 取消回覆