Gatsby - IntersectionObserver is not defined

故事扮演 提交于 2020-05-28 04:38:46

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!