React Hook useEffect 缺少依赖项:updateFunction

React Hook useEffect has a missing dependency: updateFunction

我有这段代码,我在其中使用 useEffect 通过无限滚动更新我的页面。但是在编译时,我看到了这个错误

src\components\News.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;

注意:我尝试了这个问题的建议答案,但对我不起作用。

您可以查看此问题以获取更多信息:

但是您可能应该像这样将您的函数移动到 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]);

你的解决方法其实在错误里面提供了。在 dependency 数组中包含 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]);