簡體   English   中英

如何在從 API (React) 獲取數據時加載微調器

[英]How can I load a spinner while fetching data from API (React)

我正在使用 react useParams 來顯示單個電影(詳細信息)。 我還有一個條件,如果沒有圖片(在 API 中)來顯示庫存圖片。 但是,問題是當我訪問單個電影詳細信息時,庫存照片首先顯示,然后是 API 圖片。

我該如何解決這個問題或添加一個微調器,這樣我就不會先看到庫存照片。

import React from 'react'
import { Link, useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { API_KEY, IMAGE_BASE_URL } from '../config';
import NoCover from '../img/no-cover.jpg'





const SingleMovie = () => {
  const { movieId } = useParams();
  const MOVIE_API = `https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}&language=en-US`;
  //useState
  const [movieDetails, setMovieDetails] = useState([])
  //functions
  const getMovieDetails = async (API) => {
    const response = await fetch(API)
    const data = await response.json()
    //console.log(data);
    setMovieDetails(data)
    
  }
  //useEffect
  useEffect(() => {
    getMovieDetails(MOVIE_API)
  }, [MOVIE_API])
  
  const { title, poster_path } = movieDetails
  
  return (
    <>
      <h1>{title}</h1>
      <div>
        {poster_path ? (<img src={`${IMAGE_BASE_URL}${poster_path}`} alt={title} />) : (<img src={NoCover} alt={title} />)}
      </div>
      <Link to="/">Go Back</Link>
      
      </>
    
    );
}

export default SingleMovie

嘿,你可以做的是創建一個 boolean useState來顯示Loading...同時獲取數據。 像這樣:

添加:

const [loading, setLoading] = useState(false);

獲取數據的 function 在那里我添加了一個try catch所以你也看看是否有錯誤。

const getMovieDetails = async (API) => {
    setLoading(true);
    try {
      const response = await fetch(API);
      const data = await response.json();
      //console.log(data);
      setMovieDetails(data);
    } catch (error) {
      console.log('Error', error);
    } finally {
      setLoading(false);
    }
  };

然后你可以在返回中添加這個三元:

{!loading ? (
        <div>
          {poster_path ? (
            <img src={`${IMAGE_BASE_URL}${poster_path}`} alt={title} />
          ) : (
            <img src={NoCover} alt={title} />
          )}
        </div>
      ) : (
        'Loading...'
      )}

在我添加文本Loading...的地方,您可以添加微調器組件或任何您想要的!

定義一個 state 變量loading即可解決

試試這個代碼

import React from 'react'
import { Link, useParams } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { API_KEY, IMAGE_BASE_URL } from '../config';
import NoCover from '../img/no-cover.jpg'





const SingleMovie = () => {
  const { movieId } = useParams();
  const MOVIE_API = `https://api.themoviedb.org/3/movie/${movieId}?api_key=${API_KEY}&language=en-US`;
  //useState
  const [movieDetails, setMovieDetails] = useState([])
  const [loading, setLoading] = React.useState(true); // +++
  //functions
  const getMovieDetails = async (API) => {
    const response = await fetch(API)
    if(response.ok){ // +++
        const data = await response.json()
       //console.log(data);
       setMovieDetails(data);
       setLoading(false); // +++
    } // +++
    
  }
  //useEffect
  useEffect(() => {
    getMovieDetails(MOVIE_API)
  }, [MOVIE_API])
  
  const { title, poster_path } = movieDetails
  
  return (
    <>
      <h1>{title}</h1>
      // +++
      {loading ? "spinner" : (<>
      <div>
        {poster_path ? (<img src={`${IMAGE_BASE_URL}${poster_path}`} alt={title} />) : (<img src={NoCover} alt={title} />)}
      </div>
      </>)}
      // +++
      <Link to="/">Go Back</Link>
      
      </>
    
    );
}

export default SingleMovie

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM