我的API请求会循环,直到服务器发送错误。

huangapple go评论72阅读模式
英文:

my API request is looping until the server send an error

问题

以下是您要翻译的内容:

"I'm trying to get my top listened artists on spotify with the spotify API using reactjs and the spotify-web-api-node package. I also use the useState and useEffect. When I run the app the getMyTopArtists function run in loop until it gets a 426 status code, that means that the rate limit is reached. How can I fix this bug pls?"

const [topArtists, setTopArtists] = useState([]);
useEffect(() => {
      if (!accessToken) return
      
      spotifyApi.getMyTopArtists({limit: 5, time_range: 'medium_term'}).then(res => {
        setTopArtists(res.body.items.map(artist => {
          return{
            name: artist.name,
            uri: artist.uri,
            cover: artist.images.uri,
            genre: artist.genres,
          }
        }))
      })
    }, [topArtists, accessToken])
英文:

I'm trying to get my top listened artists on spotify with the spotify API using reactjs and the spotify-web-api-node package. I also use the useState and useEffect. When I run the app the getMyTopArtists function run in loop until it gets a 426 status code, that means that the rate limit is reached.
How can I fix this bug pls?

const [topArtists, setTopArtists] = useState([]);
useEffect(() => {
      if (!accessToken) return
      
      spotifyApi.getMyTopArtists({limit: 5, time_range: 'medium_term'}).then(res => {
        setTopArtists(res.body.items.map(artist => {
          return{
            name: artist.name,
            uri: artist.uri,
            cover: artist.images.uri,
            genre: artist.genres,
          }
        }))
      })
    }, [topArtists, accessToken])

答案1

得分: 1

问题在于,在useEffect钩子的依赖数组中,您包含了topArtists。因此,问题是一旦accessToken变为真值,您就会发送一个请求来获取您的热门艺术家。一旦获取了您的艺术家,您就会更新topArtists状态值。一旦topArtists被更新(由于依赖数组),useEffect再次运行,再次更新状态,如此往复。

虽然我并不是绝对的专家,但很可能React对对象数组不执行深度比较,因此即使值相同,它也会将其视为“已更改”。

在这种情况下的解决方案很简单——>只需从依赖数组中删除topArtists

或者,您可以考虑另外两种方法:

  1. 以与您执行if (!accessToken) return相同的方式执行if (topArtists.length) return,以便在获取一次后不再获取。类似地,您可以将状态的初始值设置为null,然后执行if (!topArtists) spotifyApi....
  2. 而不是使用此useEffect钩子,您可能可以将此功能附加为 .then 到您获取accessToken的位置。如果您向Spotify发送登录请求并在响应中收到令牌,您可以执行类似以下的操作:
spotifyApi.login({details}).then(res => {
  const {accessToken: myToken} = res;
  setAccessToken(myToken);
  return myToken;
}).then(token => {
   //在这里使用令牌是推荐的,因为setState不是即时的
  spotifyApi.getMyTopArtists({limit: 5, time_range: 'medium_term'}).then(res 
   => {
        setTopArtists(res.body.items.map(artist => {
          return{
            name: artist.name,
            uri: artist.uri,
            cover: artist.images.uri,
            genre: artist.genres,
          }
        }))
   }
英文:

The issue here is that in your dependency array of the useEffect hook, you included topArtists. So, what is happening is that once the accessToken becomes truthy, you send a request to fetch your top artists. Once your artists are fetched, you update topArtists state value. Once topArtists is updated (due to the dependency array), the useEffect runs again, updates State again, so on and so forth.

While I'm not the absolute expert on it, it is likely that React is not performing deep comparison for the array of objects, so even if the value is identical, it registers it as "it changed".

The solution in this case is simple --> just remove topArtists from your dependency array.

Alternatively, you could consider 2 other methods:

  1. in the same way you are doing if (!accessToken) return you can do if (topArtists.length) return to not fetch again if fetched once. Similarly, you can set the state's initial value to something like null and do if (!topArtists) spotifyApi.....
  2. instead of this useEffect hook, you might be able to attach this functionality as a .then to wherever you are obtaining the accessToken. If you are sending a login request to Spotify and receiving the token in the response, you can do something like
spotifyApi.login({details}).then(res => {
  const {accessToken:myToken} = res;
  setAccessToken(myToken);
  return myToken;
}).then(token => {
   //recommended to use the token here since setState is not instant
  spotifyApi.getMyTopArtists({limit: 5, time_range: 'medium_term'}).then(res 
   => {
        setTopArtists(res.body.items.map(artist => {
          return{
            name: artist.name,
            uri: artist.uri,
            cover: artist.images.uri,
            genre: artist.genres,
          }
        }))
   }

huangapple
  • 本文由 发表于 2023年5月10日 18:24:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217300.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定