[英]Fetch data inside useEffect hook before rendering - React
I'm building a prototype that fetches a Spotify user's playlist data in React.我正在构建一个原型,用于在 React 中获取 Spotify 用户的播放列表数据。 The data fetching is done inside a useEffect hook and sets the state of playlists variable.
数据获取在 useEffect 挂钩内完成,并设置播放列表变量的 state。 Consequently, I want to render the name of each playlist.
因此,我想渲染每个播放列表的名称。 However, it seems that the data is only fetched after rendering, causing an issue, because the state is not set before rendering, so playlists variable is undefined.
但是,似乎只是在渲染后才获取数据,导致出现问题,因为在渲染之前未设置 state,因此未定义播放列表变量。 How can I solve this problem while continuing to use React hooks?
如何在继续使用 React 钩子的同时解决这个问题? My code is below.
我的代码如下。
import './App.css'
import queryString from 'query-string'
import React, { useState, useEffect } from 'react'
const App = () => {
const [userData, setUserData] = useState({})
const [accesstoken, setAccesstoken] = useState('')
const [playlists, setPlaylists] = useState({})
useEffect(() => {
let parsed = queryString.parse(window.location.search)
let accesstoken = parsed.access_token
if (!accesstoken) {
return
}
setAccesstoken(accesstoken)
fetch('https://api.spotify.com/v1/me', {
headers: {'Authorization': 'Bearer ' + accesstoken}
}).then(response => response.json())
.then(data => setUserData(data))
fetch(`https://api.spotify.com/v1/me/playlists`, {
headers: {'Authorization': 'Bearer ' + accesstoken}
}).then(response => response.json())
.then(data => setPlaylists(data))
}, [])
return(
<div>
{accesstoken ? (
<div>
<h1>Welcome, {userData.display_name}</h1>
<h2>Playlists</h2>
<div>
{playlists.items.map(playlist =>
<p>
{playlist.name}
</p>
)}
</div>
</div>
) : (
<button onClick={() => window.location = 'http://localhost:8888/login'}>Login</button>
)}
</div>
);
}
export default App;
You can add a check.您可以添加支票。 see below
{playlists && playlists?
见下文
{playlists && playlists?
import './App.css'
import queryString from 'query-string'
import React, { useState, useEffect } from 'react'
const App = () => {
const [userData, setUserData] = useState({})
const [accesstoken, setAccesstoken] = useState('')
const [playlists, setPlaylists] = useState({})
useEffect(() => {
let parsed = queryString.parse(window.location.search)
let accesstoken = parsed.access_token
if (!accesstoken) {
return
}
setAccesstoken(accesstoken)
fetch('https://api.spotify.com/v1/me', {
headers: {'Authorization': 'Bearer ' + accesstoken}
}).then(response => response.json())
.then(data => setUserData(data))
fetch(`https://api.spotify.com/v1/me/playlists`, {
headers: {'Authorization': 'Bearer ' + accesstoken}
}).then(response => response.json())
.then(data => setPlaylists(data))
}, [])
return(
<div>
{accesstoken ? (
<div>
<h1>Welcome, {userData.display_name}</h1>
<h2>Playlists</h2>
<div>
{playlists && playlists?.items.map(playlist =>
<p>
{playlist.name}
</p>
)}
</div>
</div>
) : (
<button onClick={() => window.location = 'http://localhost:8888/login'}>Login</button>
)}
</div>
);
}
export default App;
Use conditional rendering
.使用
conditional rendering
。 Check for values in render检查渲染中的值
<div>
{userData && <h1>Welcome, {userData.display_name}</h1>}
<h2>Playlists</h2>
{playlists && playlists.items && (
<div>
{playlists.items.map((playlist) => (
<p>{playlist.name}</p>
))}
</div>
)}
</div>;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.