首页 > 解决方案 > 组件重新渲染时页面跳转(ReactJS/Gatsby)

问题描述

描述问题

我正在为某人制作一个非常简单的 ReactJS/Gatsby 网站,但我的一个功能样式组件在重新渲染时遇到了问题。问题是它导致重新渲染完成后窗口跳转(滚动)。

重新渲染由用户单击li触发函数的 span 元素(包含在元素中)触发。

元素列表li由组件的状态决定。整个父组件具有固定的高度,这就是我无法诊断问题的原因。

我期望发生的事情

要重新渲染的组件和窗口的滚动位置保持在用户启动它时的位置。

实际发生了什么

当用户单击元素时,页面似乎会跳转(滚动)。有时它这样做并保持在新位置,有时它这样做然后返回到原始滚动位置。

我试过的

我尝试遵循其他问题的建议,这些问题建议使用event.preventDefault(),其他问题建议将样式移出组件本身,而是选择使用类。

这些解决方案都不起作用。

我已经设法明确地发现问题是由于 setActiveTabs - 这会导致ul元素的重新渲染 - 因为window.scrollY在它触发之前和完成之后记录都会显示不同的值。

编辑2:

我已经设法弄清楚问题在于使列表项可定位。似乎添加tabIndex="0"属性或使li子元素成为交互式元素会导致此错误。

有谁知道解决这个问题的方法?

编辑

完整的前端源代码可以在以下 GitHub 存储库中找到:https ://github.com/MakingStuffs/resinfusion

标签: javascriptreactjsgatsbystyled-componentsreact-functional-component

解决方案


为了解决这个问题,我需要防止被点击的元素被重新渲染。为了做到这一点,我编辑了 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)
  }

推荐阅读