I am trying to build my gatsby project but I am unable due to the IntersectionObserver not being recognized. I use the intersectionObserver inside an InView component:
import React, { useRef, useState, useEffect } from 'react'
const InView = ({ children }) => {
const [boundingClientY, setBoundingClientY] = useState(null)
const [direction, setDirection] = useState(null)
const [element, setElement] = useState(null)
const [inView, setInView] = useState(false)
const observer = useRef(new IntersectionObserver((entries) => {
const first = entries[0]
const { boundingClientRect } = first
first.isIntersecting && setInView(true)
!first.isIntersecting && setInView(false)
boundingClientRect.y > boundingClientY && setDirection('down')
boundingClientRect.y < boundingClientY && setDirection('up')
boundingClientY && setBoundingClientY(first.boundingClientRect.y)
}))
useEffect(() => {
const currentElement = element
const currentObserver = observer.current
currentElement && currentObserver.observe(currentElement)
// console.log(currentObserver)
return () => {
currentElement && currentObserver.unobserve(currentElement)
};
}, [element])
const styles = {
opacity: inView ? 1 : 0,
transform: `
translateY(${!inView ?
direction === 'up' ? '-20px' : '20px'
: 0})
rotateY(${!inView ? '35deg' : 0})
scale(${inView ? 1 : 0.9})
`,
transition: 'all 0.4s ease-out 0.2s'
}
return (
<div ref={setElement} style={styles}>
{children}
</div>
)
}
export default InView
I have a wrapper for the root element to enable a global state and have tried importing the polyfill inside gatsby-browser.js:
import React from 'react'
import GlobalContextProvider from './src/components/context/globalContextProvider'
export const wrapRootElement = ({ element }) => {
return (
<GlobalContextProvider>
{element}
</GlobalContextProvider>
)
}
export const onClientEntry = async () => {
if (typeof IntersectionObserver === `undefined`) {
await import(`intersection-observer`);
}
}
The Intersection Observer API lets code register a callback function that is executed whenever an element they wish to monitor enters or exits another element (or the viewport), or when the amount by which the two intersect changes by a requested amount.
A simple state hook for when an element is within the viewport. useInView is a tiny (0.6kb) hook that detects when the provided element is within the viewport. function Component() { const ref = useRef(null)
This is an error on build, right ($ gatsby build)? If that's the case this has nothing to do with browser support.
It is the fact that IntersectionObserver
is a browser API and you should not use browser APIs during server side rendering. Instead you try to utilize them after components have mounted. To solve this initialize your observer in useEffect()
instead of useRef()
as you currently do.
...
const observer = useRef();
useEffect(() => {
observer.current = new IntersectionObserver({ ... });
}, []); // do this only once, on mount
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With