如何在外部依赖项下使用React useCallback和useEffect

时间:2019-11-06 14:18:08

标签: reactjs react-hooks

我正在尝试遵循react-plugin-react-hooks。

我有一个useEffect,它向windowonScroll)添加了一个事件侦听器。 onScroll使用了window.pageYOffset

function onScroll() {
    if (window.pageYOffset > 0) {
      setFoor(bar)
    } else {
      setFoor(baz)
    }
  }

现在在useEffect中,我有:

useEffect(() => {
    window.addEventListener('scroll', onScroll);
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
    };
  }, []);

这遵循最初支持的建议,即如果您传递一个空的依赖项数组,则类似于componentDidMount。但是React文档明确指出,您应该不传递任何依赖项(甚至不传递空数组),或者传递所有依赖项(指的是props或state)。 (https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies)如下所示:

useEffect(() => {
    window.addEventListener('scroll', onScroll);
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
    };
  }, [onsScroll]);

但这意味着我必须对useCallback使用onScroll,否则它将始终具有不同的依赖关系。但是useCallback的{​​{1}}“依赖关系”将是onScroll,但这是行不通的,即:

window.pageYOffset

我的一般问题是,如何处理具有外部依赖项的function onScroll = React.useCallback(() => { if (window.pageYOffset > 0) { setFoor(bar) } else { setFoor(baz) } }, [window.pageYOffset]) / useEffect函数? (除了忽略警告。)

谢谢

我还尝试将useCallback的定义完全移到onScroll内,但是没有正确更新。

useEffect

2 个答案:

答案 0 :(得分:0)

依赖关系应该是props或state,在这里,您有一个定义为依赖项的类方法,在您的情况下,我想您要以类似于componentDidMount的效果安装事件监听器,可以通过将一个空数组设置为依赖性。在这种情况下,这是正确的,因为效果中的逻辑未在组件范围内使用任何变量。

在事件处理程序中,我将通过设置pageoffset的值来更改状态,而在其他效果中,请将该状态用作依赖项

答案 1 :(得分:0)

即使您在useEffect内定义了滚动处理程序,您仍在访问外部的偏移量,您需要在内部跟踪依赖项数组以及slim状态变量。

您可以使用setState的函数形式简化onScroll函数,在这种情况下,您将不再需要跟踪slim状态变量:

useEffect(() => {
  function onScroll() {
    setSlim(currentSlim => window.pageYOffset > 0 && !currentSlim)
  }

  window.addEventListener('scroll', onScroll, onScrollOptions);
  getAccountAction();
  return () => {
    window.removeEventListener('scroll', onScroll, onScrollOptions);
  };
}, [window.pageYOffset]);