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>
</>
)
}
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"
onLoad={() => 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