I have an app with some route ID's (basically a bunch of sections in a long SPA) that I have defined manually. I fetch these in gatsby-browser.js
and use them in conjunction with shouldUpdateScroll
, checking if the route ID exist, and in that case, scroll to the position of the route/section.
Example:
export const shouldUpdateScroll = ({ routerProps: { location } }) => {
const container = document.querySelector('.site')
const { pathname } = location
const projectRoutes = [`project1`, `project2`]
if (projectRoutes.indexOf(pathname) !== -1) {
const target = document.getElementById(pathname)
container.scrollTop = target.offsetTop;
}
return false
}
This works well for my usecase.
Now I want to add something similar for a page where the content is dynamically created (fetched from Sanity). From what I understand I cannot use GraphQL in gatsby-browser.js
, so what is the best way to get the ID's from Sanity to gatsby-browser.js
so I can use them to identify their scroll positions?
If there's some other better way to achieve the same result I'm open to that of course.
I think that you are over complexing the issue. You don't need the gatsby-browser.js
to achieve it.
First of all, because you are accessing directly to the DOM objects (using document.getElementById
) and you are creating precisely a virtual DOM with React to avoid pointing the real DOM. Attacking directly the real DOM (like jQuery does) has a huge performance impact in your applications and may cause some issues since in the SSR ( S erver- S ide R endering) the element may not be created yet.
You are hardcoding a logic part (the id
s) on a file that is not intended to do so.
I think you can achieve exactly the same result using a simple function using a few hooks.
You can get the same information as document.getElementById
using useRef
hook and scrolling to that position once needed.
const YourComponent= (props) => {
const sectionOne = useRef(null);
const sectionTwo = useRef(null);
useEffect(()=>{
if(typeof window !== `undefined`){
console.log("sectionOne data ",sectionOne.current)
console.log("sectionTwo data ",sectionTwo.current)
if(sectionOne) window.scrollTo( 0, 1000 ); // insert logic and coordinates
}
}, [])
return (
<>
<section ref={sectionOne}>Section 1</section>
<section ref={sectionTwo}>Section 2</section>
</>
);
}
You can isolate that function into a separate file in order to receive some parameters and return some others to achieve what you want. Basically, the snippet above creates a reference for each section and, once the DOM tree is loaded ( useEffect
with empty deps
, []
) do some stuff based on your logic.
Your document.getElementById
is replaced for sectionOne.current
(note the .current
), initially set as null
to avoid unmounting or cache issues when re-hidration occurs.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.