是否绝对需要将useEffect中的所有变量都列为依赖项?

时间:2019-10-30 13:59:47

标签: reactjs react-hooks use-effect

是否绝对需要将useEffect内部使用的所有变量始终无一例外地明确指定为依赖项?

我的用例(为演示目的而简化)涉及根据浏览器窗口的宽度执行不同的功能,但在浏览器窗口更改时不运行:

const scrollToTop = () => window.scrollTo(0, 0)
const scrollToTopOfArticle = () => window.scrollTo(0, 200)

function App({
  isDesktop,
  selectedArticle
}) {

  useEffect(() => {
    isDesktop ? scrollToTop() : scrollToTopOfArticle()
  }, [selectedArticle])

  return (
    <div className="App">
      <h1>{selectedArticle.title}</h1>
      <p>{selectedArticle.body}</p>
    </div>
  );
}

如果我将isDesktop添加到依赖项中,则每当用户调整移动设备和桌面之间的窗口大小时,效果便会运行,这是不希望的,但我也意识到,必须将效果中使用的所有内容都列为依赖性。

关于如何调和这两个要求的任何建议?

2 个答案:

答案 0 :(得分:3)

如果您只想对useEffect()中的变化做出响应,请使用selectedArticleisDesktop初始化组件状态。每当selectedArticle发生变化时,第一个selectedArticle会使用传入的道具更新两种状态,并触发第二个useEffect()在下一个渲染器上重新运行。

useEffect()

或者,您可以将此闩锁行为抽象为另一个钩子,以便const scrollToTop = () => window.scrollTo(0, 0) const scrollToTopOfArticle = () => window.scrollTo(0, 200) function App({ isDesktop, selectedArticle }) { const [desktop, setDesktop] = useState(isDesktop) const [article, setArticle] = useState(selectedArticle) useEffect(() => { if (article !== selectedArticle) { setDesktop(isDesktop) setArticle(selectedArticle) } }, [isDesktop, selectedArticle, article]) useEffect(() => { if (desktop) scrollToTop() else scrollToTopOfArticle() }, [desktop, article]) return ( <div className="App"> <h1>{selectedArticle.title}</h1> <p>{selectedArticle.body}</p> </div> ) } 仅在isDesktop更改时更新为其有效值。请注意,selectedArticle仍然需要依赖于滚动动作效果,因此即使selectedArticle尚未更改,useEffect()也会在对selectedArticle的每次更改时触发滚动动作自上次触发以来更改的值。

isDesktop

答案 1 :(得分:1)

  

是否绝对需要将useEffect中的所有变量都列为依赖项?

是,否则会生成警告。

这就是为什么最好清楚地知道每种效果应该做什么(即分离关注点)。

因此,您可以具有两种具有不同依赖性的单独效果。

类似的东西:

useEffect(
  () => {
    scrollToTopOfArticle();
  }, [selectedArticle]
);

useEffect(
  () => {
    if (selectedArticle && isDesktop) {
      scrollToTop();
    }
  }, [isDesktop, selectedArticle]
)