Gatsby JS:预加载器永远加载
Gatsby JS: Preloader is loading forever
我通过 jQuery 在我的 Gatsby 应用程序上复制了一个简单的整页预加载器。然而,预加载器可以工作,而不是在 4 秒后消失,它在生产环境中永远加载,但在本地它工作得很好。
这是我的 Preloader
组件:
import React from 'react'
const Preloader = () => {
return (
<div id="loader-wrapper">
<div id="loader"></div>
<div className="loader-section section-left"></div>
<div className="loader-section section-right"></div>
</div>
)
}
export default Preloader
然后在我的 script.js
(包含在 <Helmet>
中):
jQuery.noConflict();
(function ($) {
var windows = $(window);
/* preloader */
setTimeout(function(){
$('body').addClass('loaded');
$('h1').css('color','#222222');
}, 400);
})(jQuery);
我在 index.js
:
上添加了这个预加载器
return (
<>
<Preloader />
<SEO />
<div className="main-container">
<Layout>
<Header />
<Testimonials title="Testimonials" />
<Blogs title="Latest Blogs" blogs={blogs} showAllBlogLinks/>
<Map />
</Layout>
</div>
</>
)
}
知道是什么原因造成的以及如何解决吗?
您是否尝试过将您的代码添加到 gatsby-browser.js
而不是像这样的东西?
export const onInitialClientRender = () => {
setTimeout(function() {
document.querySelector("body").classList.add("loaded");
document.querySelector("h1").style = "color: #222222";
}, 400)
}
几个月前我遇到过类似的问题,修复完全取决于实现和您的代码。基本上,正在发生的事情是 React 不明白他需要重新水合某些组件,因为在 React 的生态系统之外将某些全局对象指向 DOM 的 window
或 document
(不使用状态)可能会阻止补液,因为 jQuery.
绕过这个问题的所有可能解决方案都是补丁(比如尝试添加缓存)。理想的解决方案是避免使用直接指向 DOM 的 jQuery,以及操纵虚拟 DOM (vDOM) 的 React。这条线正在破坏你的补液:
var windows = $(window);
The most weird thing here is that on local upon running npx gatsby
develop it shows all of my data. Really weird
又不是:gatsby develop
出现在浏览器中,其中有一个 window
对象,另一方面,gatsby build
出现在没有对象的服务器(节点)中window
or other global objects 因为它们甚至还没有被创建。
此外,您可以轻松转换此代码段:
setTimeout(function() {
document.querySelector("body").classList.add("loaded");
document.querySelector("h1").style = "color: #222222";
}, 400)
进入基于 React 的,使用钩子:
const [loader, setLoader]=useState(true);
useEffect(()=>{
setTimeout(()=> {
setLoader(false)
}, 400)
}, [])
return (
<>
<SEO />
{loader
? <Preloader />
: <div className="main-container">
<Layout>
<Header />
<Testimonials title="Testimonials" />
<Blogs title="Latest Blogs" blogs={blogs} showAllBlogLinks/>
<Map />
</Layout>
</div>
}
</>
)
}
作为简历。您最初将加载程序设置为 true (useState(true)
),并且一旦 DOM 树被加载(useEffect
with empty deps
, []
),您触发您的 setTimeout
函数,它将 loader
的值从 true
切换为 false
。这将选择使用三元条件渲染的组件:loader ? <Preloader/> : <OtherComponents />
如果您需要使用 window
大小的对象,您可以使用基于 React 的方法,例如提供的方法 here。
Is there a way to improve this and make the preloader loads everytime
you visit another page?
是的,我们的想法是将该加载程序逻辑移动到 <Layout>
组件,因为所有页面都将共享它:
const Layout = ({ children }) => {
const [loader, setLoader]=useState(true);
useEffect(()=>{
setTimeout(()=> {
setLoader(false)
}, 400)
}, [])
return <section className={`site__wrapper`}>
<Header />
<main>{loader ? <Preloader/> : children}</main>
</section>;
};
我不知道你的 <Layout>
组件是什么样子,但我的想法是添加类似的东西。由于您的 <Layout>
在您的网站上共享,每次重新呈现组件都会重新水化该组件,强制初始加载器状态为 true
并在 400 毫秒时将其更改为 false
,呈现children
,这是包裹在其他页面上的 <Layout>
组件中的所有内容。
我通过 jQuery 在我的 Gatsby 应用程序上复制了一个简单的整页预加载器。然而,预加载器可以工作,而不是在 4 秒后消失,它在生产环境中永远加载,但在本地它工作得很好。
这是我的 Preloader
组件:
import React from 'react'
const Preloader = () => {
return (
<div id="loader-wrapper">
<div id="loader"></div>
<div className="loader-section section-left"></div>
<div className="loader-section section-right"></div>
</div>
)
}
export default Preloader
然后在我的 script.js
(包含在 <Helmet>
中):
jQuery.noConflict();
(function ($) {
var windows = $(window);
/* preloader */
setTimeout(function(){
$('body').addClass('loaded');
$('h1').css('color','#222222');
}, 400);
})(jQuery);
我在 index.js
:
return (
<>
<Preloader />
<SEO />
<div className="main-container">
<Layout>
<Header />
<Testimonials title="Testimonials" />
<Blogs title="Latest Blogs" blogs={blogs} showAllBlogLinks/>
<Map />
</Layout>
</div>
</>
)
}
知道是什么原因造成的以及如何解决吗?
您是否尝试过将您的代码添加到 gatsby-browser.js
而不是像这样的东西?
export const onInitialClientRender = () => {
setTimeout(function() {
document.querySelector("body").classList.add("loaded");
document.querySelector("h1").style = "color: #222222";
}, 400)
}
几个月前我遇到过类似的问题,修复完全取决于实现和您的代码。基本上,正在发生的事情是 React 不明白他需要重新水合某些组件,因为在 React 的生态系统之外将某些全局对象指向 DOM 的 window
或 document
(不使用状态)可能会阻止补液,因为 jQuery.
绕过这个问题的所有可能解决方案都是补丁(比如尝试添加缓存)。理想的解决方案是避免使用直接指向 DOM 的 jQuery,以及操纵虚拟 DOM (vDOM) 的 React。这条线正在破坏你的补液:
var windows = $(window);
The most weird thing here is that on local upon running npx gatsby develop it shows all of my data. Really weird
又不是:gatsby develop
出现在浏览器中,其中有一个 window
对象,另一方面,gatsby build
出现在没有对象的服务器(节点)中window
or other global objects 因为它们甚至还没有被创建。
此外,您可以轻松转换此代码段:
setTimeout(function() {
document.querySelector("body").classList.add("loaded");
document.querySelector("h1").style = "color: #222222";
}, 400)
进入基于 React 的,使用钩子:
const [loader, setLoader]=useState(true);
useEffect(()=>{
setTimeout(()=> {
setLoader(false)
}, 400)
}, [])
return (
<>
<SEO />
{loader
? <Preloader />
: <div className="main-container">
<Layout>
<Header />
<Testimonials title="Testimonials" />
<Blogs title="Latest Blogs" blogs={blogs} showAllBlogLinks/>
<Map />
</Layout>
</div>
}
</>
)
}
作为简历。您最初将加载程序设置为 true (useState(true)
),并且一旦 DOM 树被加载(useEffect
with empty deps
, []
),您触发您的 setTimeout
函数,它将 loader
的值从 true
切换为 false
。这将选择使用三元条件渲染的组件:loader ? <Preloader/> : <OtherComponents />
如果您需要使用 window
大小的对象,您可以使用基于 React 的方法,例如提供的方法 here。
Is there a way to improve this and make the preloader loads everytime you visit another page?
是的,我们的想法是将该加载程序逻辑移动到 <Layout>
组件,因为所有页面都将共享它:
const Layout = ({ children }) => {
const [loader, setLoader]=useState(true);
useEffect(()=>{
setTimeout(()=> {
setLoader(false)
}, 400)
}, [])
return <section className={`site__wrapper`}>
<Header />
<main>{loader ? <Preloader/> : children}</main>
</section>;
};
我不知道你的 <Layout>
组件是什么样子,但我的想法是添加类似的东西。由于您的 <Layout>
在您的网站上共享,每次重新呈现组件都会重新水化该组件,强制初始加载器状态为 true
并在 400 毫秒时将其更改为 false
,呈现children
,这是包裹在其他页面上的 <Layout>
组件中的所有内容。