[英]How can I load a spinner while fetching data from API (React)
I am using react useParams to show a singleMovie (details).我正在使用 react useParams 来显示单个电影(详细信息)。 I have also a condition that if there is no picture (in the API) to show a stock picture.
我还有一个条件,如果没有图片(在 API 中)来显示库存图片。 However, the problem is that when I access the single movie detail the stock photo shows first then the API picture.
但是,问题是当我访问单个电影详细信息时,库存照片首先显示,然后是 API 图片。
How can I fix this or add a spinner so that I dont see the stock photo first.我该如何解决这个问题或添加一个微调器,这样我就不会先看到库存照片。
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
Hey what you can do is create a boolean useState
to display a Loading... while getting the data.嘿,你可以做的是创建一个 boolean
useState
来显示Loading...同时获取数据。 Like this:像这样:
Add:添加:
const [loading, setLoading] = useState(false);
The function that gets the data, there I added a try catch
so also you see if there is an error.获取数据的 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);
}
};
And then you can add this ternary in the return:然后你可以在返回中添加这个三元:
{!loading ? (
<div>
{poster_path ? (
<img src={`${IMAGE_BASE_URL}${poster_path}`} alt={title} />
) : (
<img src={NoCover} alt={title} />
)}
</div>
) : (
'Loading...'
)}
Where I added the text Loading...
, you can add a spinner component or whatever you want!在我添加文本
Loading...
的地方,您可以添加微调器组件或任何您想要的!
define a state variable loading
can be solved定义一个 state 变量
loading
即可解决
Try out this code试试这个代码
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.