组件重新渲染时页面跳转 (ReactJS/Gatsby)
Page Jumps on Component Re-Render (ReactJS/Gatsby)
描述问题
我正在为某人制作一个非常简单的 ReactJS/Gatsby 网站,但我在重新呈现时遇到了我的功能样式组件之一的问题。问题是它导致 window 在重新渲染完成后跳转(滚动)。
重新渲染由用户点击触发函数的 span 元素(包含在 li
元素中)触发。
li
个元素的列表由组件的状态决定。整个父组件的高度是固定的,这就是我无法诊断问题的原因。
我期望发生的事情
要重新呈现的组件和 window 的滚动位置保持在用户启动它时的位置。
实际发生了什么
当用户单击该元素时,页面会跳转(滚动)。有时它这样做并保持在新位置,有时它这样做然后 returns 到原始滚动位置。
我试过的
我尝试遵循其他问题的建议,建议使用 event.preventDefault()
和其他建议将样式移出组件本身,而是选择使用 类.
这些解决方案均无效。
我已经设法明确地发现问题是由于 setActiveTabs 引起的——它导致 ul
元素的重新渲染——在触发之前和之后记录 window.scrollY
它完成显示不同的值。
编辑 2:
我已经设法弄清楚问题在于使列表项可定位。似乎添加 tabIndex="0"
属性或使 li
子元素成为交互式元素会导致此错误。
有人知道解决这个问题的方法吗?
编辑
完整的前端源代码可以在以下 GitHub 存储库中找到:https://github.com/MakingStuffs/resinfusion
为了解决这个问题,我需要防止被点击的元素被重新渲染。为此,我编辑了 clickHandler,以便它在设置状态后使用 element.blur()
。
点击处理如下:
const forwardClickHandler = event => {
setLoading(true)
const clickedSlug =
event.target.closest("button") !== null
? event.target.closest("button").getAttribute("data-slug")
: event.target.children[0].getAttribute("data-slug")
const categoryObject = getNeedle(clickedSlug, categories, "slug")
const subCatObject = getNeedle(clickedSlug, subCategories, "slug")
const serviceObject = getNeedle(clickedSlug, services, "slug")
const associatedChildren = getAssociatedChildren(
categoryObject
? categoryObject
: subCatObject
? subCatObject
: serviceObject
)
setBgImage(associatedChildren[0].thumb.localFile.childImageSharp.fluid)
setActiveTabs(associatedChildren)
event.target.blur()
return setTimeout(() => setLoading(false), 1000)
}
描述问题
我正在为某人制作一个非常简单的 ReactJS/Gatsby 网站,但我在重新呈现时遇到了我的功能样式组件之一的问题。问题是它导致 window 在重新渲染完成后跳转(滚动)。
重新渲染由用户点击触发函数的 span 元素(包含在 li
元素中)触发。
li
个元素的列表由组件的状态决定。整个父组件的高度是固定的,这就是我无法诊断问题的原因。
我期望发生的事情
要重新呈现的组件和 window 的滚动位置保持在用户启动它时的位置。
实际发生了什么
当用户单击该元素时,页面会跳转(滚动)。有时它这样做并保持在新位置,有时它这样做然后 returns 到原始滚动位置。
我试过的
我尝试遵循其他问题的建议,建议使用 event.preventDefault()
和其他建议将样式移出组件本身,而是选择使用 类.
这些解决方案均无效。
我已经设法明确地发现问题是由于 setActiveTabs 引起的——它导致 ul
元素的重新渲染——在触发之前和之后记录 window.scrollY
它完成显示不同的值。
编辑 2:
我已经设法弄清楚问题在于使列表项可定位。似乎添加 tabIndex="0"
属性或使 li
子元素成为交互式元素会导致此错误。
有人知道解决这个问题的方法吗?
编辑
完整的前端源代码可以在以下 GitHub 存储库中找到:https://github.com/MakingStuffs/resinfusion
为了解决这个问题,我需要防止被点击的元素被重新渲染。为此,我编辑了 clickHandler,以便它在设置状态后使用 element.blur()
。
点击处理如下:
const forwardClickHandler = event => {
setLoading(true)
const clickedSlug =
event.target.closest("button") !== null
? event.target.closest("button").getAttribute("data-slug")
: event.target.children[0].getAttribute("data-slug")
const categoryObject = getNeedle(clickedSlug, categories, "slug")
const subCatObject = getNeedle(clickedSlug, subCategories, "slug")
const serviceObject = getNeedle(clickedSlug, services, "slug")
const associatedChildren = getAssociatedChildren(
categoryObject
? categoryObject
: subCatObject
? subCatObject
: serviceObject
)
setBgImage(associatedChildren[0].thumb.localFile.childImageSharp.fluid)
setActiveTabs(associatedChildren)
event.target.blur()
return setTimeout(() => setLoading(false), 1000)
}