React警告我必须添加一个“图像”依赖项,但当我这样做时,它会循环并关闭所有依赖项。我可以对“图像”做些什么,使它们不会改变每个渲染吗?
const App = () => {
const [imageName, setImageName] = useState('');
const [images, setImages] = useState([]);
const [page, setPage] = useState(1);
const [error, setError] = useState(null);
const [status, setStatus] = useState(Status.IDLE);
const [isShowBtn, setIsShowBtn] = useState(false);
useEffect(() => {
if (!imageName) {
setStatus(Status.IDLE);
setImages([]);
setIsShowBtn(false);
}
if (imageName !== '' || page > 1) {
setStatus(Status.PENDING);
fetchImages(imageName, page)
.then(({ data }) => {
const imagesValue = images.concat(data.hits);
setImages(
imagesValue.map(({ id, webformatURL, largeImageURL }) => ({
id,
webformatURL,
largeImageURL,
}))
);
setIsShowBtn(data.totalHits > imagesValue.length);
setStatus(Status.RESOLVED);
})
.catch(error => {
console.log(error);
setError(error);
setStatus(Status.REJECTED);
});
}
}, [imageName, page]);
const handleSearchSubmit = imageName => {
setImageName(imageName);
setPage(1);
};
const handleLoadMoreClick = () => {
setPage(page => page + 1);
setIsShowBtn(false);
};
return (
<div className="app">
<Searchbar onSubmit={handleSearchSubmit} />
{status === Status.REJECTED && <p>Error: {error.message}</p>}
<ImageGallery imageName={imageName} images={images} status={status} />
{status === Status.PENDING && <Loader />}
{isShowBtn && <Button onClick={handleLoadMoreClick} />}
</div>
);
};
我尝试将“imagesValue”移出,但它受到提取的严格影响。此外,我将提取的整个函数移到useEffect并在那里调用它,但没有起作用。此外,尝试了useMemo和useCallback,但也没有修复。
1条答案
按热度按时间xdnvmnnf1#
嗯......这里的经验法则是,无论何时useEffect实际上改变了“图像”和“状态”,你都应该将它们作为useEffect中的依赖项。为了清楚起见,我将“状态.挂起”切换为“挂起”,将“状态.空闲”切换为“空闲”,等等。也许这样做有潜在的原因......只是看起来多余。
因此,我们需要告诉React,如果fetchImages fn已经被调用并且承诺已经实现,那么它应该跳过fetchImages。
这里潜在的想法是如果
我们将状态设置为PENDING。2 useEffect将在那里结束他的回合。3然后,因为状态在你的依赖项数组中,useEffect将再次被调用,这次status ===“PENDING”将为真,我们将获取图像。
当履行承诺时,fetchImages将状态更新为“RESOLVED”或“REJECTED”,因此fetchImages不会再次触发。
如果您有时间,请阅读https://overreacted.io/a-complete-guide-to-useeffect/下面的文章
这个对我理解useEffect行为帮助很大。干杯。