我正在创建一个词汇表页面,其中每个术语都有其自己的卡,默认情况下不会展开。每张卡都使用术语作为其ID,因为它们都是唯一的。我想支持通过URL哈希直接链接到特定术语。
因此,如果URL是localhost:3000 /#/ glossary#Actor,则初始加载将滚动到该术语并通过模拟元素的单击来“打开”卡(该元素上的单击处理程序将打开卡)
它正在工作,但是太频繁了。每当我在搜索栏中输入文本或以任何方式引起渲染时,它都会重新滚动并再次打开卡片动画。我只想首先滚动到该术语(如果存在哈希值),然后忽略它,除非它发生变化。
仅当我不包含dep数组时才有效。如果我在props.location.hash中包含一个dep数组,则el返回为null,并且什么也没有发生。我知道,由于没有dep数组,因此正在重新启动效果,但是我不知道为什么在添加它时它不起作用。
useEffect(() => {
//looks for hash in URL; gets element associated with the hash
let el = document.getElementById(decodeURI(props.location.hash.slice(1)));
console.log(el)
//if element exists, get coords and offset for header before scrolling
if (el) {
const yCoordinate = el.getBoundingClientRect().top + window.pageYOffset;
const yOffset = -80;
window.scrollTo({
top: yCoordinate + yOffset,
behavior: 'smooth'
});
//opens the card only if not already open
if (!el.classList.contains('openTermCard')) {
el.click();
}
}
})
useEffect可能不是正确的方法。我什至不需要钩子,idk。我只希望此初始滚动事件在页面加载时发生,而不是再次发生。
答案 0 :(得分:0)
在没有可用的沙箱的情况下很难找到解决方案。
根据您的描述,在我看来,您的组件在第一次加载时渲染了多次。如果将[]
设置为依赖项数组,则在尚未定义元素时,效果仅运行一次(因此,得到null
的原因),这就是为什么它不起作用的原因。
一种解决方法是考虑在设计应用程序方面还可以做些什么。您提到每次组件更新时,卡都会再次聚焦,但这就是您使用useEffect
时的期望。是否可以重新构造组件,以便父级(具有这种副作用的组件)不经常重新渲染?
如果您可以提供代码沙箱,我相信我(可能还有其他人)将能够为您提供进一步的帮助。