问题
I am trying to build my gatsby project but I am unable due to the IntersectionObserver not being recognised. 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`);
}
}
回答1:
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
...
来源:https://stackoverflow.com/questions/59424347/gatsby-intersectionobserver-is-not-defined