如何正确使用useEffect()



我想通过滚动来更改样式。

此代码工作不正常。当我上下滚动的次数太多、速度太快时,浏览器就会冻结、崩溃。

我想我用错了useEffect()。我该如何解决这个问题。

const ArticleItem = ({title, content, active, chapter, program, id, scrollPos}) => {
const ref = useRef(null);
const client = useApolloClient();
useEffect(() => {
if(ref.current.offsetTop <= (scrollPos + 200)) {
client.writeData({data: {
curChapter: chapter.num,
curArticle: id,
curProgram: program.name
}});
}
});
if(active === false)
return ( // Inactive Article
<div className='section-item' ref={ref}>
<h2>{title.toUpperCase()}</h2>
<ReactMarkdown source={content} />
<br />
</div>
)
return (  // Active Article
<div className='section-item active' ref={ref}>
<h2>{title.toUpperCase()}</h2>
<ReactMarkdown source={content} />
<br />
</div>
)
}

因此,我面临这个警告。

警告:超过了最大更新深度。当组件在useEffect内部调用setState时,可能会发生这种情况,但useEffect没有依赖项数组,或者每次渲染时都会更改其中一个依赖项。

我认为这就是问题的原因?!

根据我上面的评论,您还需要包括useEffect的依赖数组。按照目前的方式,它是无限运行的。您可能希望将scrollPos包含在其中,因此它只会在scrollPos发生更改时触发。

尝试以下操作:

useEffect(() => {
if(ref.current.offsetTop <= (scrollPos + 200)) {
client.writeData({data: {
curChapter: chapter.num,
curArticle: id,
curProgram: program.name
}});
}
}, [scrollPos]);

我希望这能有所帮助!

好吧,问题总是会被触发的——你可以使用scroll事件监听器,并在触发该事件时进行更改。

const [scrollItem, setScrollItem] = useState(null);
const handleScroll() {
if(scrollItem) {
// logic goes here
}
}
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []); // initialize event only once
return (
<div ref={setScrollItem}>
...
</div>
);

编辑

避免这种解决方案,@norbitrial是正确的

相关内容

  • 没有找到相关文章

最新更新