Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.0k views
in Technique[技术] by (71.8m points)

reactjs - Fetch data inside useEffect hook before rendering - React

I'm building a prototype that fetches a Spotify user's playlist data in React. The data fetching is done inside a useEffect hook and sets the state of playlists variable. 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. How can I solve this problem while continuing to use React hooks? 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;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Use 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>;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...