React Hook useEffect缺少一个依赖项:updateFunction



我有这个代码,我使用useEffect来更新我的页面无限滚动。然而,在编译相同的代码时,我看到了这个错误

srccomponentsNews.js
Line 40:6:  React Hook useEffect has missing dependencies: 'props.category' and 'updateNews'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

但是当我在依赖数组[page, props.category, updateNews]中包含此函数时,我得到了另一个错误

Line 17:9:  The 'updateNews' function makes the dependencies of useEffect Hook (at line 40) change on every render. Move it inside the useEffect callback. Alternatively, wrap the definition of 'updateNews' in its own useCallback() Hook  react-hooks/exhaustive-deps
下面是我的代码:每当用户滚动页面编号时,页面编号就会更新,并且调用use Effect钩子,这反过来又调用updateNews函数。
import React, { useEffect, useState } from "react";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
import PropTypes from "prop-types";
import InfiniteScroll from "react-infinite-scroll-component";
const News = (props) => {
const [articles, setArticles] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(1);
const [totalResults, setTotalResults] = useState(0);
const capitalizeFirstLetter = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
const updateNews = async () => {
props.setProgress(10);
let goToPage = page;
const url = `https://newsapi.org/v2/top-headlines?country=${props.country}&category=${props.category}&apiKey=${props.apiKey}&page=${goToPage}&pageSize=${props.pageSize}`;
props.setProgress(30);
let data = await fetch(url);
props.setProgress(50);
let parsedData = await data.json();
props.setProgress(70);
if (parsedData) {
setArticles(articles.concat(parsedData.articles));
setLoading(false);
setPage(page);
setTotalResults(parsedData.totalResults);
}
props.setProgress(100);
};
useEffect(() => {
updateNews();
// eslint-disable-next-line

document.title = `${capitalizeFirstLetter(props.category)} - NewsMonkey`;
}, [page, props.category]);
const fetchMoreData = async () => {
setPage(page + 1);
};
return (
<>
<h3 className="text-center" style={{ marginTop: "4%" }}>
NewsMonkey - Top {`${capitalizeFirstLetter(props.category)}`} Headlines
</h3>
{loading && <Spinner />}
<InfiniteScroll
dataLength={articles.length}
next={fetchMoreData}
hasMore={articles.length < totalResults}
loader={<Spinner />}
>
<div className="container">
<div className="row">
{articles.map((element) => {
return (
<div className="col-md-4" key={element.url}>
<NewsItem
title={
element && element.title ? element.title.slice(0, 45) : ""
}
description={
element && element.description
? element.description.slice(0, 50)
: ""
}
imageUrl={element.urlToImage}
newsUrl={element.url}
author={element.author}
date={element.publishedAt}
source={element.source.name}
/>
</div>
);
})}
</div>
</div>
</InfiniteScroll>
</>
);
};
export default News;

注意:我试着用我得到的答案作为这个问题的建议,但那对我不起作用。

您的解决方案实际上在错误中提供。在将updateNews包含在依赖数组中之后,在每个渲染器上没有任何记忆,React将始终看到updateNews !== updateNews,这是由于JS的性质(即使是相同编写的函数也永远不会彼此相等)。

updateNews函数包装在useCallback中基本上允许React知道该函数在每个渲染中都是相同的,直到它的依赖数组项之一改变。

这个应该可以工作:

const updateNews = useCallback(async () => {
props.setProgress(10);
let goToPage = page;
const url = `https://newsapi.org/v2/top-headlines?country=${props.country}&category=${props.category}&apiKey=${props.apiKey}&page=${goToPage}&pageSize=${props.pageSize}`;
props.setProgress(30);
let data = await fetch(url);
props.setProgress(50);
let parsedData = await data.json();
props.setProgress(70);
if (parsedData) {
setArticles(articles.concat(parsedData.articles));
setLoading(false);
setPage(page);
setTotalResults(parsedData.totalResults);
}
props.setProgress(100);
}, [page, props.country, props.category, props.apiKey, props.pageSize]);
useEffect(() => {
updateNews();
// eslint-disable-next-line

document.title = `${capitalizeFirstLetter(props.category)} - NewsMonkey`;
}, [props.category, updateNews]);

您可以查看此问题以获取更多信息:如何在使用useEffect React Hook时修复缺失的依赖警告

但是你应该把你的函数移到useEffect里面,像这样:

useEffect(() => {
const updateNews = async () => {
props.setProgress(10);
let goToPage = page;
const url = `https://newsapi.org/v2/top-headlines?country=${props.country}&category=${props.category}&apiKey=${props.apiKey}&page=${goToPage}&pageSize=${props.pageSize}`;
props.setProgress(30);
let data = await fetch(url);
props.setProgress(50);
let parsedData = await data.json();
props.setProgress(70);
if (parsedData) {
setArticles(articles.concat(parsedData.articles));
setLoading(false);
setPage(page);
setTotalResults(parsedData.totalResults);
}
props.setProgress(100);
};
updateNews();    
document.title = `${capitalizeFirstLetter(props.category)} - NewsMonkey`;
}, [page, props.category]);

相关内容