Gatsby JS:预加载器永远加载 [英] Gatsby JS: Preloader is loading forever
问题描述
我在Gatsby应用程序上通过jQuery复制了一个简单的整页预加载器.但是,预加载器可以正常工作,而不会在4秒钟后消失,而是永远在生产环境中消失,而在本地则可以正常工作.
这是我的 Preloader
组件:
import从'react'进行Reactconst Preloader =()=>{返回 (< div id ="loader-wrapper">< div id =加载程序">/div< div className ="loader-section section-left"</div< div className ="loader-section section-right"</div</div>)}导出默认的预加载器
然后在我的 script.js
(包含在< Helmet>
中)上:
jQuery.noConflict();(函数($){var windows = $(window);/*预加载器*/setTimeout(function(){$('body').addClass('loaded');$('h1').css('color','#222222');},400);})(jQuery);
我在 index.js
上添加了此预加载器:
返回(<><预加载器/>< SEO/>< div className =主容器"><布局><标题/><推荐书标题=推荐书"./>< Blogs title =最新博客";blogs = {blogs} showAllBlogLinks/><地图/></布局></div></>)}
您知道是什么原因造成的,以及如何解决此问题?
几个月前,我也遇到了类似的问题,解决方法严格取决于实现和您的代码.基本上,正在发生的事情是,React's不了解他需要补充水分,因为指向一些全局对象,如React之外的DOM的 window
或 document
生态系统(不使用状态)可能会由于jQuery而阻止补液.
所有可能绕过此问题的解决方案都是修补程序(例如尝试添加缓存).理想的解决方案是避免使用带有操纵虚拟DOM(vDOM)的React的直接指向DOM的jQuery.这条线破坏了您的补液功能:
var windows = $(window);
最奇怪的是在本地运行npx gatsby时开发它可以显示我的所有数据.真的很奇怪
这不是,再次出现: gatsby开发
在浏览器中发生,在浏览器中有一个 window
对象,另一方面,发生了 gatsby build
在没有 window
或其他服务器的服务器(节点)中全局对象,因为它们甚至都没有创建.
此外,您可以轻松转换此代码段:
setTimeout(function(){document.querySelector("body").classList.add("loaded");document.querySelector("h1").style =颜色:#222222";},400)
使用钩子插入基于React的容器中:
const [loader,setLoader] = useState(true);useEffect(()=> {setTimeout(()=> {setLoader(假)},400)},[])返回 (<>< SEO/>{loader?<预加载器/>:< div className =主容器"><布局><标题/><推荐书标题=推荐书"./>< Blogs title =最新博客";blogs = {blogs} showAllBlogLinks/><地图/></布局></div>}</>)}
作为简历.您最初将加载程序设置为true( useState(true)
),然后在加载DOM树后( useEffect
且空的 deps
, []
),则触发您的 setTimeout
函数,该函数会将 loader
的值从 true
切换为 false
.这将在以下位置使用三元条件选择要渲染的组件: loader?<预加载器/>:< OtherComponents/>
如果需要使用 window
大小对象,则可以使用基于React的方法,例如提供的此处.
有没有一种方法可以改善这种情况并使每次加载预加载器您访问另一个页面?
是的,因为所有页面将共享它,所以想法是将加载程序逻辑移至< Layout>
组件.
const Layout =({childrens))=>{const [loader,setLoader] = useState(true);useEffect(()=> {setTimeout(()=> {setLoader(假)},400)},[])返回< section className = {`site__wrapper`}><标题/>< main> {loader?<预加载器/>:children}</main></section> ;;};
我不知道您的< Layout>
组件的外观如何,但是其想法是添加类似的内容.由于您的< Layout>
在您的站点之间共享,因此每次重新渲染组件都会对该组件进行补水,从而将初始加载程序状态强制为 true
并将其更改为 false
(400毫秒),呈现 children
,这是包装在其他页面上的< Layout>
组件中的所有内容.
I copied a simple full page preloader via jQuery on my Gatsby app. The preloader works however instead of disappearing after 4 seconds its loading forever on production but on local it works just fine.
Here's my Preloader
component:
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
And then on my script.js
(which was included inside <Helmet>
):
jQuery.noConflict();
(function ($) {
var windows = $(window);
/* preloader */
setTimeout(function(){
$('body').addClass('loaded');
$('h1').css('color','#222222');
}, 400);
})(jQuery);
I added this preloader on my index.js
:
return (
<>
<Preloader />
<SEO />
<div className="main-container">
<Layout>
<Header />
<Testimonials title="Testimonials" />
<Blogs title="Latest Blogs" blogs={blogs} showAllBlogLinks/>
<Map />
</Layout>
</div>
</>
)
}
Any idea what's causing this and how to fix it?
I've faced a similar issue a few months ago and the fix depends strictly on the implementation and your code. Basically, what is happening is that React's doesn't understand that he needs to rehydrate some components because pointing to some global objects as window
or document
of the DOM, outside the React's ecosystem (without using states) may block that rehydration, in your cause, because of jQuery.
All the possible solutions that bypass this issue will be patches (like trying to add the cache). The ideal solution would avoid using jQuery, which points directly to the DOM, with React, which manipulates the virtual DOM (vDOM). This line is breaking your rehydration:
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
It's not, again: gatsby develop
occurs in the browser, where there's a window
object, on the other hand, gatsby build
occurs in the server (Node) where there's no window
or other global objects because they are not even created.
In addition, you can easily transform this snippet:
setTimeout(function() {
document.querySelector("body").classList.add("loaded");
document.querySelector("h1").style = "color: #222222";
}, 400)
Into a React-based one, using hooks:
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>
}
</>
)
}
As a resume. You are setting initially the loader as true (useState(true)
), and once the DOM tree is loaded (useEffect
with empty deps
, []
), you trigger your setTimeout
function, which toggles the value of loader
from true
to false
. This will choose what component render using a ternary condition at: loader ? <Preloader/> : <OtherComponents />
If you need to use the window
size object, you can use a React-based approach, like the one provided here.
Is there a way to improve this and make the preloader loads everytime you visit another page?
Yes, the idea is to move that loader logic to the <Layout>
component, since all the pages will share it:
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>;
};
I don't know how your <Layout>
component looks like but the idea is to add something similar. Since your <Layout>
is shared across your site, each re-rendering of the component will rehydrate this component, forcing the initial loader state as true
and changing it to false
at 400ms, rendering the children
, which is everything wrapped inside the <Layout>
component on other pages.
这篇关于Gatsby JS:预加载器永远加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!