reactjs - gatsby + react hook masonry 在构建时中断,因为没有窗口
问题描述
我设置了一个反应挂钩来处理我的 gatsby 网站某些页面上的砌体。问题是它引用了服务器端不存在的窗口对象gatsby build
。我读过解决方案是将 useEffect 包装为:
if (typeof window === 'undefined') {
}
但是我似乎无法包装我的砌体文件的正确部分。我还读到使用上述技巧会使服务器端渲染变得毫无意义,不确定。
有人可以告诉我 if 语句应该放在我下面的砌体文件中的什么位置吗?它不是一个插件,它是我的 utils 文件夹中的一个钩子。使用这个 tut 中的代码。我已经尝试了 useEffects 中的 if 语句,围绕 useEffects,围绕整个 eventListener,但没有骰子。谢谢!!
import React, { useEffect, useRef, useState } from "react"
import styled from "styled-components"
const useEventListener = (eventName, handler, element = window) => {
const savedHandler = useRef()
useEffect(() => {
savedHandler.current = handler
}, [handler])
useEffect(() => {
const isSupported = element && element.addEventListener
if (!isSupported) return
const eventListener = event => savedHandler.current(event)
element.addEventListener(eventName, eventListener)
return () => {
element.removeEventListener(eventName, eventListener)
}
}, [eventName, element])
}
const fillCols = (children, cols) => {
children.forEach((child, i) => cols[i % cols.length].push(child))
}
export default function Masonry({ children, gap, minWidth = 500, ...rest }) {
const ref = useRef()
const [numCols, setNumCols] = useState(3)
const cols = [...Array(numCols)].map(() => [])
fillCols(children, cols)
const resizeHandler = () =>
setNumCols(Math.ceil(ref.current.offsetWidth / minWidth))
useEffect(resizeHandler, [])
useEventListener(`resize`, resizeHandler)
const MasonryDiv = styled.div`
margin: 1rem auto;
display: grid;
grid-auto-flow: column;
grid-gap: 1rem;
`
const Col = styled.div`
display: grid;
grid-gap: 1rem;
`
return (
<MasonryDiv ref={ref} gap={gap} {...rest}>
{[...Array(numCols)].map((_, index) => (
<Col key={index} gap={gap}>
{cols[index]}
</Col>
))}
</MasonryDiv>
)
}
解决方案
在您gatsby-node.js
添加以下代码段:
exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
if (stage === "build-html") {
actions.setWebpackConfig({
module: {
rules: [
{
test: /masonry/,
use: loaders.null(),
},
],
},
})
}
}
注意:/masonry/
使用node_modules
.
来自有关调试 HTML 构建的 Gatsby 文档:
构建静态 HTML 文件时出现错误通常是由于以下原因之一:
您的一些代码引用了“浏览器全局变量”,例如窗口或文档。如果这是您的问题,您应该会看到上面的错误,例如“<code>window is not defined”。要解决此问题,请找到有问题的代码,然后 a) 在调用代码之前检查是否定义了窗口,因此代码在 Gatsby 构建时不会运行(请参见下面的代码示例)或 b) 如果代码在渲染函数中一个 React.js 组件,将该代码移动到
componentDidMount
生命周期或useEffect
钩子中,以确保代码不会运行,除非它在浏览器中。
或者,您可以将导入的 Masonry 钩子用法包装在此语句中:
if (typeof window !== `undefined`) {
const module = require("module")
}
请注意!==
比较,而不是===
您提供的比较。
推荐阅读
- javascript - JavaScript:需要输入元素以根据输入的数据更改选项
- python - 反复收到消息:您正在通过 HTTPS 访问开发服务器,但它只支持 HTTP
- ruby-on-rails - 命名作业是一个好习惯吗?
- python - scipy.integrate.solve_bvp 用于 Neumann 边界条件?
- wordpress - 如何将替代文本添加到实际上是无声、循环、自动播放 MP4 的 GIF
- javascript - 如何在 Typescript 中验证数组为空
- javascript - p5.js:随机颜色并保存为 pdf 功能
- java - 对齐缩进
- rules - 规则不执行
- function - 谁能弄清楚如何测试这个 OCAML 功能?