Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React Hooks JS Lint warning Useffect缺少依赖项_Reactjs_React Hooks - Fatal编程技术网

Reactjs React Hooks JS Lint warning Useffect缺少依赖项

Reactjs React Hooks JS Lint warning Useffect缺少依赖项,reactjs,react-hooks,Reactjs,React Hooks,我正在查看react的文档,因为我在js linter中遇到了这个错误。我试着像文档中显示的那样修改代码,但我觉得我遗漏了什么,因为我仍然会遇到同样的错误。我将在尝试之前和之后发布代码。谢谢 warning React Hook useEffect has a missing dependency: 'handleDocumentScrollThrottled'. Either include it or remove the dependency array react-hooks/exh

我正在查看react的文档,因为我在js linter中遇到了这个错误。我试着像文档中显示的那样修改代码,但我觉得我遗漏了什么,因为我仍然会遇到同样的错误。我将在尝试之前和之后发布代码。谢谢

warning  React Hook useEffect has a missing dependency: 'handleDocumentScrollThrottled'. Either include it or remove the dependency array  react-hooks/exhaustive-deps
尝试修复前的代码

/* Completed useDocumentScrollThrottled utility function */

import { useEffect, useState } from 'react';
import { throttle } from 'lodash';

function useDocumentScrollThrottled(callback) {
  const [, setScrollPosition] = useState(0);
  let previousScrollTop = 200;

  function handleDocumentScroll() {
    const { scrollTop: currentScrollTop } = document.documentElement || document.body;

    setScrollPosition(previousPosition => {
      previousScrollTop = previousPosition;
      return currentScrollTop;
    });

    callback({ previousScrollTop, currentScrollTop });
  }

  const handleDocumentScrollThrottled = throttle(handleDocumentScroll, 250);

  useEffect(() => {
    window.addEventListener('scroll', handleDocumentScrollThrottled);

    return () =>
      window.removeEventListener('scroll', handleDocumentScrollThrottled);
  }, []);
}

export default useDocumentScrollThrottled;
...

useEffect(() => {

    function doSomething(){
      window.addEventListener('scroll', handleDocumentScrollThrottled);

    return () =>
      window.removeEventListener('scroll', handleDocumentScrollThrottled);
    } 

    doSomething();

  }

  ...
尝试修复后的代码

/* Completed useDocumentScrollThrottled utility function */

import { useEffect, useState } from 'react';
import { throttle } from 'lodash';

function useDocumentScrollThrottled(callback) {
  const [, setScrollPosition] = useState(0);
  let previousScrollTop = 200;

  function handleDocumentScroll() {
    const { scrollTop: currentScrollTop } = document.documentElement || document.body;

    setScrollPosition(previousPosition => {
      previousScrollTop = previousPosition;
      return currentScrollTop;
    });

    callback({ previousScrollTop, currentScrollTop });
  }

  const handleDocumentScrollThrottled = throttle(handleDocumentScroll, 250);

  useEffect(() => {
    window.addEventListener('scroll', handleDocumentScrollThrottled);

    return () =>
      window.removeEventListener('scroll', handleDocumentScrollThrottled);
  }, []);
}

export default useDocumentScrollThrottled;
...

useEffect(() => {

    function doSomething(){
      window.addEventListener('scroll', handleDocumentScrollThrottled);

    return () =>
      window.removeEventListener('scroll', handleDocumentScrollThrottled);
    } 

    doSomething();

  }

  ...

错误不会得到解决,因为您正在将依赖项包装到另一个函数中。doSomething exmaple文档中建议的方法是将函数移出钩子的范围。这在您的情况下是不可能的,因为您的handleDocumentScroll依赖于仅在钩子中可用的setter

相反,你必须:

将handleDocumentScrollThrottled的依赖项添加到依赖项数组中,如下所示:

  useEffect(() => {
    //...
  }, [handleDocumentScrollThrottled]);
这当然不起作用,因为handleDocumentScrollThrottled在每次渲染时都会重新分配,因此每次都会触发此效果。那很可能不是你想要的

这里的解决方案是为handleDocumentScrollThrottled使用一个记忆值,以便它不会在每次重新渲染时更改:

  const handleDocumentScrollThrottled = useMemo(() => {
    function handleDocumentScroll() {
      const { scrollTop: currentScrollTop } = document.documentElement || document.body;

      setScrollPosition(previousPosition => {
        previousScrollTop = previousPosition;
        return currentScrollTop;
      });

      callback({ previousScrollTop, currentScrollTop });
    }

    return throttle(handleDocumentScroll, 250);
  }, []);

然而,我想指出的是,滥用setter设置另一个变量是非常有技巧的,您可能应该使用ref来跟踪旧的滚动位置。

这看起来是使用ref跟踪滚动位置的更好方法吗@安德森:是的,这就是我的意思。使用ref允许您在使用状态设置器时立即访问设置值。这在下一次渲染之前是不可用的,在您的情况下,这已经太晚了,但不会引入可能的副作用。