简体   繁体   English

React Hook useEffect 缺少依赖项:updateFunction

[英]React Hook useEffect has a missing dependency: updateFunction

I have this code, where I am using useEffect to update my page with the infinite scroll.我有这个代码,我在那里使用 useEffect 用无限滚动更新我的页面。 However while compiling the same, I see this error但是在编译时,我看到了这个错误

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

But when I am including this function in the dependency array [page, props.category, updateNews] I am getting another error但是当我在依赖数组[page, props.category, updateNews]包含这个函数时[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

Here is my code : Whenever user scrolls the page number is updated and the use Effect hook is being called, which in turn is calling the updateNews function.这是我的代码: 每当用户滚动页码时都会更新并调用 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;

Note : I tried the answer that I was getting as suggestion to this question but that did not work for me.注意:我尝试了作为对这个问题的建议而得到的答案,但这对我不起作用。

Your solution is actually provided inside the error.您的解决方案实际上是在错误中提供的。 After including updateNews inside the dependency array, without any memorization on every rerender React will always see updateNews !== updateNews , which is due to the nature of JS (even equally written functions will never be equal to one another).在依赖数组中包含updateNews之后,在每次重新渲染时没有任何记忆,React 总是会看到updateNews !== updateNews ,这是由于 JS 的性质(即使相同编写的函数也永远不会彼此相等)。

Wrapping the updateNews function inside useCallback basically allows React to know that this function will be the same on every rerender until one of its dependency array items change.updateNews函数包装在useCallback基本上可以让 React 知道这个函数在每次重新渲染时都是相同的,直到它的依赖项数组项之一发生变化。

This should work:这应该有效:

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]);

You can look into this issue for more informations : How to fix missing dependency warning when using useEffect React Hook您可以查看此问题以获取更多信息: How to fix missing dependency warning when using useEffect React Hook

But you should probably just move your function inside the useEffect like so :但是你可能应该像这样将你的函数移动到 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]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM