我希望有人可以帮助我解决重新获取数据时遇到的问题。在初始页面渲染上,我正在获取显示有关随机电影的信息的数据,然后,当用户单击页面上的“下一步”按钮时,将显示新的随机电影。我遇到的问题是,它似乎重新获取了两次数据,这意味着单击一次按钮时,会弹出一秒钟的新电影,然后是另一段。 >
经过数小时的搜寻后,我似乎无法找到此问题的确切解决方案,但我怀疑这是我使用useEffect挂钩的方式:
const Movie = () => {
const [pageNo, setPageNo] = useState(1);
const [movieNo, setMovieNo] = useState(1);
const [movie, setMovie] = useState('');
const [isLoading, setIsLoading] = useState(true);
const [imageUrl, setImageUrl] = useState('https://image.tmdb.org/t/p/');
function handleClick(e) {
e.preventDefault();
setMovieNo(Math.floor(Math.random() * 20));
setPageNo(Math.floor(Math.random() * 500 + 1));
}
async function fetchData(page) {
const result = await axios(
`https://api.themoviedb.org/3/discover/movie?api_key=a035c9128c767a8b70c9413632d63cd0&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}&vote_average.gte=1.0`
);
setMovie(result.data.results);
setIsLoading(false);
}
useEffect(() => {
fetchData(pageNo);
}, [pageNo]);
return (
...
);
};
很抱歉,如果这个问题不是很清楚,我从来都不擅长于解释问题
答案 0 :(得分:0)
罪魁祸首是此功能。 两次更改状态(movieNo,pageNo分别更改一次)会使页面呈现两次。
function handleClick(e) {
e.preventDefault();
setMovieNo(Math.floor(Math.random() * 20));
setPageNo(Math.floor(Math.random() * 500 + 1));
}
完成示例代码以重现问题
import React, { useState, useEffect } from "react";
import axios from "axios";
const Movie = () => {
const [pageNo, setPageNo] = useState(1);
const [movieNo, setMovieNo] = useState(1);
const [movie, setMovie] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [imageUrl, setImageUrl] = useState("https://image.tmdb.org/t/p/");
function handleClick(e) {
e.preventDefault();
setMovieNo(Math.floor(Math.random() * 20));
setPageNo(Math.floor(Math.random() * 500 + 1));
}
async function fetchData(page) {
const result = await axios(
`https://api.themoviedb.org/3/discover/movie?api_key=a035c9128c767a8b70c9413632d63cd0&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}&vote_average.gte=1.0`
);
setMovie(result.data.results);
setIsLoading(false);
}
useEffect(() => {
fetchData(pageNo);
}, [pageNo]);
return (
<div>
<p>{isLoading ? "" : movie[movieNo].title}</p>
<button onClick={handleClick}>next</button>
</div>
);
};
export default Movie;
在此处修复
const [rank, setRank] = useState({ pageNo: 1, movieNo: 1 });
setRank({
pageNo: Math.floor(Math.random() * 500 + 1),
movieNo: Math.floor(Math.random() * 20)
});
修复后完成代码。
import React, { useState, useEffect } from "react";
import axios from "axios";
const Movie = () => {
const [rank, setRank] = useState({ pageNo: 1, movieNo: 1 });
const [movie, setMovie] = useState("");
const [isLoading, setIsLoading] = useState(true);
const [imageUrl, setImageUrl] = useState("https://image.tmdb.org/t/p/");
function handleClick(e) {
e.preventDefault();
setRank({
pageNo: Math.floor(Math.random() * 500 + 1),
movieNo: Math.floor(Math.random() * 20)
});
}
async function fetchData(page) {
setIsLoading(true);
const result = await axios(
`https://api.themoviedb.org/3/discover/movie?api_key=a035c9128c767a8b70c9413632d63cd0&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}&vote_average.gte=1.0`
);
setMovie(result.data.results);
setIsLoading(false);
}
useEffect(() => {
fetchData(rank.pageNo);
}, [rank]);
return (
<div>
<p>{isLoading ? "loading..." : movie[rank.movieNo].title}</p>
<button onClick={handleClick}>next</button>
</div>
);
};
export default Movie;
总而言之,useEffect没有错。 多次更改状态会导致您的组件多次渲染。尝试将所有这些条件合并为一个状态,以便更易于管理。