useEffect中的所有变量是否都必须作为依赖项列出



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添加到依赖项中,那么每当用户在移动和桌面之间调整窗口大小时,效果就会运行,这是不希望的,但我也知道效果中使用的所有东西都必须列为依赖项。

关于如何协调这两个要求,有什么建议吗?

如果要使useEffect()仅响应selectedArticle的更改,请使用isDesktopselectedArticle初始化组件状态。每当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仍然需要是滚动动作效果的依赖项,因此即使isDesktop自上次触发以来没有改变值,useEffect()也会在每次更改selectedArticle时触发滚动动作。

const useLatch = (value, deps) => {
const [state, setState] = useState(value)
const effect = useCallback(() => { setState(value) }, [value])
useEffect(effect, deps)
return state
}
const scrollToTop = () => window.scrollTo(0, 0)
const scrollToTopOfArticle = () => window.scrollTo(0, 200)
function App({
isDesktop,
selectedArticle
}) {
const latchedIsDesktop = useLatch(isDesktop, [selectedArticle])
useEffect(() => {
if (latchedIsDesktop) scrollToTop()
else scrollToTopOfArticle()
}, [latchedIsDesktop, selectedArticle])
return (
<div className="App">
<h1>{selectedArticle.title}</h1>
<p>{selectedArticle.body}</p>
</div>
)
}

useEffect中的所有变量都必须作为依赖项列出吗?

是,否则将生成警告。

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

因此,您可以有两个具有不同依赖关系的独立效果。

类似于:

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

相关内容

  • 没有找到相关文章

最新更新