盖茨比 - IntersectionObserver 未定义
Gatsby - IntersectionObserver is not defined
我正在尝试构建我的 gatsby 项目,但由于无法识别 IntersectionObserver 而无法构建。我在 InView 组件中使用 intersectionObserver:
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
我有一个根元素的包装器来启用全局状态,并尝试在 gatsby 中导入 polyfill-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`);
}
}
这是构建错误,对吧($ gatsby build)?如果是这样的话,这与浏览器支持无关。
事实上 IntersectionObserver
是一个浏览器 API,您不应该在服务器端呈现期间使用浏览器 API。相反,您尝试在组件安装后使用它们。要解决此问题,请在 useEffect()
中初始化您的观察者,而不是像您目前所做的那样在 useRef()
中初始化。
...
const observer = useRef();
useEffect(() => {
observer.current = new IntersectionObserver({ ... });
}, []); // do this only once, on mount
...
声明一个 let 变量 = null。这也适用于 NextJS
...
let observer = null
useEffect(()=> {
observer = new IntersectionObserver(callback,optional);
},[])
IntersectionObserver API 是一个浏览器 API,它不能在 Gatsby 构建过程中执行。因此,您应该在浏览器中检查您的代码是否为运行:
let observer = null;
if (typeof window !== "undefined"){ // The code inside brackets will be executed ONLY in browser
observer = new IntersectionObserver(/* ... */);
// ...
}
我正在尝试构建我的 gatsby 项目,但由于无法识别 IntersectionObserver 而无法构建。我在 InView 组件中使用 intersectionObserver:
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
我有一个根元素的包装器来启用全局状态,并尝试在 gatsby 中导入 polyfill-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`);
}
}
这是构建错误,对吧($ gatsby build)?如果是这样的话,这与浏览器支持无关。
事实上 IntersectionObserver
是一个浏览器 API,您不应该在服务器端呈现期间使用浏览器 API。相反,您尝试在组件安装后使用它们。要解决此问题,请在 useEffect()
中初始化您的观察者,而不是像您目前所做的那样在 useRef()
中初始化。
...
const observer = useRef();
useEffect(() => {
observer.current = new IntersectionObserver({ ... });
}, []); // do this only once, on mount
...
声明一个 let 变量 = null。这也适用于 NextJS
...
let observer = null
useEffect(()=> {
observer = new IntersectionObserver(callback,optional);
},[])
IntersectionObserver API 是一个浏览器 API,它不能在 Gatsby 构建过程中执行。因此,您应该在浏览器中检查您的代码是否为运行:
let observer = null;
if (typeof window !== "undefined"){ // The code inside brackets will be executed ONLY in browser
observer = new IntersectionObserver(/* ... */);
// ...
}