Reactjs 使用自定义布局组件反应useEffect奇怪行为

Reactjs 使用自定义布局组件反应useEffect奇怪行为,reactjs,react-hooks,next.js,use-effect,Reactjs,React Hooks,Next.js,Use Effect,我正在尝试在我的网络公文包中使用滚动位置作为动画。由于这个公文包使用nextJS,我不能依赖窗口对象,而且我使用的是导航范围的滑块,所以我实际上不是在窗口中滚动,而是在一个名为Page的布局组件中滚动 import React, { useEffect } from 'react'; import './page.css'; const Page = ({ children }) => { useEffect(() => { const scrollX = docum

我正在尝试在我的网络公文包中使用滚动位置作为动画。由于这个公文包使用nextJS,我不能依赖窗口对象,而且我使用的是导航范围的滑块,所以我实际上不是在窗口中滚动,而是在一个名为Page的布局组件中滚动

import React, { useEffect } from 'react';
import './page.css';

const Page = ({ children }) => {

  useEffect(() => {
    const scrollX = document.getElementsByClassName('page')
    const scrollElement = scrollX[0];
    console.log(scrollX.length)
    console.log(scrollX)
    scrollElement.addEventListener("scroll", function () {
      console.log(scrollX[0].scrollTop)
    });
 
    return () => {
      scrollElement.removeEventListener("scroll", () => { console.log('listener removed') })
    }
  }, [])


  return <div className="page">{children}</div>;
};

export default Page;
import React,{useffect}来自“React”;
导入“/page.css”;
常量页=({children})=>{
useffect(()=>{
const scrollX=document.getElementsByClassName('page'))
常量scrollElement=scrollX[0];
console.log(scrollX.length)
console.log(scrollX)
scrollElement.addEventListener(“滚动”,函数(){
console.log(scrollX[0].scrollTop)
});
return()=>{
scrollElement.removeEventListener(“scroll”,()=>{console.log('listener removed')})
}
}, [])
返回{children};
};
导出默认页面;
这是一个生产构建:

加载时,DOM中只有一个页面组件

行为如下:

  • 在第一个页面装载时添加第一个侦听器,在导航时,还将在DOM中添加一个新的页面组件
  • 只要在这两个页面之间导航,就不会添加新的侦听器/页面
  • 如果导航到第三页,则在卸载旧页时删除侦听器,并在装载第三页时添加第三页的新侦听器(等等)
问题是:当您从第一个导航到第二个时,一切看起来都很好,但如果返回到第一个页面,您会注意到控制台正在记录第二个侦听器的scrollX值,而不是第一个侦听器的值。每次进入第二个页面时,似乎都会向同一个scrollElement添加另一个侦听器,即使它不是同一个页面组件

我该怎么做?我猜这两个组件试图访问相同的scrollElement:/


谢谢您的时间。

很酷的网站。我们没有完整的信息,但我怀疑尝试使用
document.getElementsByClassName('page')[0]
时存在问题。当您转到第2页时,
scrollX
的日志提供了一个包含2个元素的HTMLCollection。因此,有一个问题是谁是目标。我会考虑使用裁判代替。像这样:

import React,{useffect,useRef}来自“React”;
导入“/page.css”;
常量页=({children})=>{
const pageRef=useRef(空)
常量scrollListener=()=>{
console.log(pageRef.current.scrollTop)
}
useffect(()=>{
pageRef.addEventListener(“滚动”,scrollListener);
return()=>{
pageRef.removeEventListener(“滚动”,scrollListener)
}
}, [])
返回{children};
};
导出默认页面;
这是一个非常干净,我认为将减少组件之间关于每个滚动监听器引用的dom元素的混淆。到第三页为止,您的
scrollX
仍在记录相同的HTMLElement集合,包含2个元素。根据你的模式,应该有3个。(虽然实际上应该只有1!)因此第3页上的某些内容没有正确呈现。 如果我们看到更多的代码,它可能会发现错误是其他的东西。如果refs不能解决这个问题,你能在更大范围内发布
Page
是如何实现的吗


另外,从“初级开发人员”标题中删除“初级”,你不会后悔的

嘿,谢谢你的网站:p你的解决方案很有魅力。只需要在您提供的useEffect中将pageRef更改为pageRef.current。感谢您对useRef hook的深入了解;)