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] =].这应该确保您的 div
和 window
可用。
原来是他们这边的问题。由于他们进行了更新,因此可以正常工作。
我正在使用 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] =].这应该确保您的 div
和 window
可用。
原来是他们这边的问题。由于他们进行了更新,因此可以正常工作。