我想通过滚动更改样式。
此代码无法正常工作 。 当我上下滚动太多次且速度太快时,浏览器将冻结,崩溃。
我认为我用错了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要么没有依赖项数组,要么在每个渲染器上都有一个依赖项更改。
我认为这是问题的原因?!
答案 0 :(得分:3)
根据我上面的评论,您还需要包括useEffect
的依赖项数组。按照目前的方式,它可以无限运行。可能您想将scrollPos
包含在其中,因此只有scrollPos
发生更改时才会触发。
尝试以下操作:
useEffect(() => {
if(ref.current.offsetTop <= (scrollPos + 200)) {
client.writeData({data: {
curChapter: chapter.num,
curArticle: id,
curProgram: program.name
}});
}
}, [scrollPos]);
我希望这会有所帮助!
答案 1 :(得分:0)
好吧,问题始终在您可以使用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是正确的