是否绝对需要将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添加到依赖项中,则每当用户调整移动设备和桌面之间的窗口大小时,效果便会运行,这是不希望的,但我也意识到,必须将效果中使用的所有内容都列为依赖性。
关于如何调和这两个要求的任何建议?
答案 0 :(得分:3)
如果您只想对useEffect()
中的变化做出响应,请使用selectedArticle
和isDesktop
初始化组件状态。每当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]
)