英文:
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
。
或者,您可以考虑另外两种方法:
- 以与您执行
if (!accessToken) return
相同的方式执行if (topArtists.length) return
,以便在获取一次后不再获取。类似地,您可以将状态的初始值设置为null,然后执行if (!topArtists) spotifyApi....
。 - 而不是使用此
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:
- in the same way you are doing
if (!accessToken) return
you can doif (topArtists.length) return
to not fetch again if fetched once. Similarly, you can set the state's initial value to something like null and doif (!topArtists) spotifyApi....
. - instead of this
useEffect
hook, you might be able to attach this functionality as a.then
to wherever you are obtaining theaccessToken
. 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,
}
}))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论