简体   繁体   English

组件重新渲染时页面跳转(ReactJS/Gatsby)

[英]Page Jumps on Component Re-Render (ReactJS/Gatsby)

Describe the Problem描述问题

I am making a very simple ReactJS/Gatsby website for someone and I am having an issue with one of my functional styled components when it re-renders.我正在为某人制作一个非常简单的 ReactJS/Gatsby 网站,但我的一个功能样式组件在重新渲染时遇到了问题。 The problem is that it is causing the window to jump (scroll) after the re-render is complete.问题是它导致 window 在重新渲染完成后跳转(滚动)。

The re-render is triggered by the user clicking on a span element (enclosed in an li element) which fires a function.重新渲染由用户单击触发 function 的 span 元素(包含在li元素中)触发。

The list of li elements is determined by the state of the component. li元素列表由组件的 state 确定。 The overall parent component has a fixed height which is why I am having trouble diagnosing the issue.整个父组件具有固定的高度,这就是我无法诊断问题的原因。

What I Expect to Happen我期望发生的事情

The component to re-render and the window's scroll position to remain where it was when the user initiated it.要重新渲染的组件和窗口的滚动 position 保持在用户启动它时的位置。

What Actually Happens实际发生了什么

When the user clicks the element the page appears to jump (scroll).当用户单击元素时,页面似乎会跳转(滚动)。 Sometimes it does so and remains in the new position, sometimes it does so and then returns to the original scroll position.有时它会这样做并保留在新的 position 中,有时它会这样做然后返回到原始卷轴 position。

What I've Tried我试过的

I've tried following advice from other questions which suggest using event.preventDefault() and others which suggest moving the styling out of the component itself and, instead, opting for using classes.我已经尝试遵循其他问题的建议,这些问题建议使用event.preventDefault()和其他建议将样式从组件本身移出,而是选择使用类。

Neither of these solutions worked.这些解决方案都不起作用。

I have managed to definitively find that the issue is due to setActiveTabs -- which causes the re-render of the ul element -- as logging window.scrollY both prior to it firing and after it completes displays a different value.我已经设法明确地发现问题是由于 setActiveTabs - 这会导致ul元素的重新渲染 - 在window.scrollY在它触发之前和完成之后都记录显示不同的值。

Edit 2:编辑2:

I have managed to figure out that the issue is with making the list items targetable.我已经设法弄清楚问题在于使列表项可定位。 It seems that either adding the tabIndex="0" attribute or making the li child an interactive element causes this bug.似乎添加tabIndex="0"属性或使li子元素成为交互式元素都会导致此错误。

Does anyone know a way around this?有谁知道解决这个问题的方法?

Edit编辑

The full frontend source code can be found in the following GitHub repo: https://github.com/MakingStuffs/resinfusion完整的前端源代码可以在以下 GitHub repo 中找到: https://github.com/MakingStuffs/resinfusion

In order to solve the issue I needed to prevent the clicked element from being targeted on the re-render.为了解决这个问题,我需要防止被点击的元素被重新渲染。 In order to do this I edited the clickHandler so that it uses element.blur() after setting the state.为了做到这一点,我编辑了 clickHandler 以便它在设置 state 后使用element.blur()

The click handler is as follows:点击处理程序如下:

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)
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM