I have a problem with gatsby 5, it imports jquery and slick.js to it using "Helmet" without refreshing the page, the script works but as soon as I click f5 (clear the cache), I suddenly get an error that "$ is not defined" or that "jquery s not defined"I feel that it may be a fault that they will not load in the correct js order, but I might be wrong. Will you help?
export function Head() {
return (
<>
<title>Simtopia</title>
<Helmet>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj 3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"
integrity="sha512-XtmMtDEcNz2j7ekrtHvOVR4iwwaD6o/FUJe6 Zq HgcCsk3kj4uSQQR8weQ2QVj1o0Pk6PwYLohm206ZzNfubg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<script
src="/js/localJS.js"
></script>
</Helmet>
</>
)
}
CodePudding user response:
If you are loading scripts that are mutually dependent I'd recommend using the Script
API that Gatsby provides, which exposes an onLoad
callback:
import React, { useState } from "react";
import { Script } from "gatsby";
export function Head() {
const [loaded, setLoaded] = useState(false);
return (
<>
<Script
src="https://code.jquery.com/jquery-3.6.0.min.js"
onl oad={() => setLoaded(true)}
/>
{loaded && (
<Script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js" />
)}
{loaded && (
<Script src="/js/localJS.js" />
)}
</>
);
}
Note: tweak the order or the conditions accordingly
⚠️
Outside the scope of the question: don't import jQuery inside React apps, or you will break the hydration. Really, don't do it.
React (so Gatsby) creates and manipulates a virtual DOM (vDOM) while jQuery manipulates directly the real DOM. Using both will cause unwanted (re)hydration issues because when something changes in the DOM React won't be aware and vice-versa. This translates into multiple issues, but one of the most typical is finding unstyled parts of the page, non-rendered hooks when moving forward/backward using browser's arrows/history, etc.
From React docs:
React is unaware of changes made to the DOM outside of React. It determines updates based on its own internal representation, and if the same DOM nodes are manipulated by another library, React gets confused and has no way to recover.
Alternatively, use React-based approaches such Reack Slick or using useRef
hook when pointing DOM elements