CSS 重新加载页面时崩溃

CSS crashes when I reload page

我正在使用 Gatsby 构建站点。 我正在使用导入脚本和 returns 表单的组件。 问题是,在加载显示表单的页面后,然后单击任何其他页面并返回该表单页面,整个站点的 css 完全崩溃,您必须刷新整个页面页。 要查看我的意思,请单击此 link https://baerenherz.org/,转到菜单最右侧的深蓝色按钮,然后单击任何其他导航站点,然后再次单击蓝色按钮(jetzt -spenden).

这是我的捐赠表格组成部分:

import React, { useState, useEffect } from "react"
import {Helmet} from "react-helmet"

import Loading from "./Loading"

function Child() {
  return(
    <div style={{width: "75%", margin: "4em auto"}} >
      <Helmet>
        <script type='text/javascript' aysnc>
          {` window.rnw.tamaro.runWidget('.dds-widget-container', {language: 'de'}) `}
        </script>
      </Helmet>
      <div className="dds-widget-container"></div>
    </div>
  )
}

function RaiseNow() {
  const [loaded, setLoaded] = useState(false)

  useEffect(() => {
    const scriptTag = document.createElement('script')
    scriptTag.src='https://tamaro.raisenow.com/xxx/latest/widget.js'
    scriptTag.addEventListener('load', ()=> setLoaded(true))
    document.body.appendChild(scriptTag)
    return ()=>{
      scriptTag.removeEventListener(); // check if necessary
      setLoaded(false) // check if necessary
    }

  }, []);


  return (
    <>
      {loaded ? <Child /> : <Loading/>}
    </>
  )
      }


export default RaiseNow

我注意到,当您第二次访问该页面时,正在加载...组件甚至不再显示...显示了布局,但一旦显示表单,它就会崩溃...

由于从去年开始我就无法解决这个问题,我真的很感激任何帮助。提前谢谢你。

显然,当组件应该 mounted/unmounted 时,您的脚本正在破坏 React 的水合作用。如果没有可用的 React-based 脚本,就没有“干净”的解决方案。这里的问题是您的脚本正在操纵 DOM 而 React 管理虚拟 DOM (vDOM)。 DOM 在 React 范围之外的变化不会被 React 监听,反之亦然。

就是说,我会尝试在每次加载页面时强制加载和呈现您的小部件。类似于:

function RaiseNow() {
  const [loaded, setLoaded] = useState(false)

  useEffect(() => {
    const scriptTag = document.createElement('script')
    scriptTag.src='https://tamaro.raisenow.com/xxx/latest/widget.js'
    scriptTag.addEventListener('load', ()=> setLoaded(true))
    document.body.appendChild(scriptTag)
    window.rnw.tamaro.runWidget('.dds-widget-container', {language: 'de'})
     return ()=>{
      scriptTag.removeEventListener('load', setLoaded(false)); // check if necessary
      setLoaded(false) // check if necessary
    }  

  }, []);

  return (
    <>
      {loaded ? <Child /> : <Loading/>}
    </>
  )
}


export default RaiseNow

如果没有 CodeSandbox,很难猜测代码的行为方式,但重要的是当组件从 UI 中移除时分离并清理监听器,以避免破坏 React 的水合过程,在return 声明。来自 useEffect docs:

The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect. In our example, this means a new subscription is created on every update. To avoid firing an effect on every update, refer to the next section.

除了从脚本中移除侦听器外,您还可以将加载状态设置为 false。

我还删除了第二个 useEffect,因为避免 CSS 中断的想法是在每个页面呈现中强制加载脚本。这不是最佳解决方案,但可能对您有用。理想的解决方案是使用 React-based 依赖项。

要考虑的另一件事是延迟 rnw.tamaro 脚本的触发,直到加载 DOM 树,方法是将它从 Helmet 移动到 [=12] =].这应该确保您的 divwindow 可用。

原来是他们这边的问题。由于他们进行了更新,因此可以正常工作。