[英]gatsby setPageSection makes page jump after images finish loading
當前的這段代碼:
<button onClick={() => setPageSection([p.slug+"/", s.slug])}>
當圖像完成加載時,使我的頁面跳轉到該部分的開頭
在這種情況下,我有一個正確延遲加載的圖片網格,並使用初始 base64 低分辨率預渲染,但每次每張圖片完成加載頁面都會滾動回該部分的頂部。
這僅在我使用 setPageSection 時發生。 當我單擊指向頁面錨點(“page/#section”)的直接鏈接而不是使用上述設置頁面部分的方法時,會發生正確的行為(圖像繼續在后台延遲加載並且頁面不會捕捉每次完成加載時都到該部分的頂部)。
更新:以下看起來像罪魁禍首:
enter useEffect(() => {
if (typeof prevPageSection === 'undefined') return;
const scrollToSection = () => {
const el = document.getElementById(pageSection[1]);
if (scrollContainer.current && el) {
scrollContainer.current.scrollTo({ top: el.offsetTop });
}
};
if (pageSection[0] !== prevPageSection![0] && pageSection[0] !== pageContext.slug) {
navigate(locale + pageSection[0]);
scrollContainer.current?.addEventListener('load', scrollToSection, true);
}
scrollContainer.current?.removeEventListener('load', scrollToSection);
}, [pageSection, prevPageSection, locale, pageContext.slug]);
如果我刪除這些事件偵聽器,則頁面在圖像加載后停止跳轉,但鏈接被破壞(導航到不同頁面上的某個部分時它們變得無用,沒有這些事件偵聽器,如果已經在該頁面上,則只能跳轉到所需的部分,否則瀏覽器將導航到頁面頂部)
你的useEffect
鈎子有太多的副作用。 每次更改一個依賴項( pageSection
或prevPageSection
或locale
或pageContext.slug
)時,它都會觸發鈎子,從而產生您不想要的效果:
const el = document.getElementById(pageSection[1]);
if (scrollContainer.current && el) {
scrollContainer.current.scrollTo({ top: el.offsetTop });
}
此外,不要在 useEffect 中定義useEffect
,因為它會在每次觸發效果時創建一個新的作用域 function,從而使您的代碼和應用程序過載。
此外,不要使用document.getElementById()
直接指向 DOM。 對於瀏覽器來說,這是一個高成本的操作,您可以使用 useRef 鈎子實現相同的效果,使用useRef
鈎子的.current
屬性,您將獲得完全相同的信息,與使用useRef
的方式scrollContainer.current
。 實際上,您正在使用 React 創建和操作虛擬 DOM,以避免在您的代碼攻擊真實 DOM 時指向 DOM。
請注意全局對象的使用,例如window
或 Gatsby 中的document
,它們在 SSR 期間不可用(服務器-S ide R )因此它們可能會破壞您的代碼。 總而言之, gatsby build
在您的 Node 服務器中編譯代碼,其中沒有window
或document
,因為它甚至還沒有創建。 該代碼可以在gatsby develop
下運行,因為它是由瀏覽器直接呈現的。
要解決您的問題,我會清理useEffect
,您可以根據需要創建任意數量的效果,並且可以使用此表示法命名它們以使您的代碼更具可讀性:
useEffect(someNamedFunction(){
// your code
}, []).
為了更快地繞過它,您可以創建一個輔助 function 強制頁面滾動到某個元素而不涉及掛鈎:
const scrollToElement=(el)=>{
scrollContainer.current.scrollTo({ top: el.offsetTop });
}
<button onClick={(el)=> scrollToElement(el)}>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.