【发布时间】:2020-05-07 16:22:53
【问题描述】:
我设置了一个反应挂钩来处理我的 gatsby 网站某些页面上的砌体。问题是它引用了窗口对象,该对象在服务器端gatsby build 上不存在。 I've read that the solution is to wrap useEffect with:
if (typeof window === 'undefined') {
}
但是我似乎无法包装我的砌体文件的正确部分。我还读到使用上述技巧会使服务器端渲染变得毫无意义,不确定。
有人能告诉我 if 语句应该放在我下面的砌体文件中的什么位置吗?它不是一个插件,它是我的 utils 文件夹中的一个钩子。 Using code from this 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>
)
}
【问题讨论】:
-
你可能想使用 masonic 或 react-masonry-component 之类的东西,而不是尝试在 React 中重新实现 Masonry。
-
我想要一种特定类型的柱状砌体,但 div 按时间顺序从左到右阅读,否则会完全使用它
-
啊,有趣!
标签: reactjs window react-hooks gatsby