[英]How to get an component height to trigger Headroom in React?
這是我第一次與 Gatsby 和 React 打交道,所以我可能在這件事上使用了錯誤的方法。 無論如何,這就是正在發生的事情。
從 gatsby-starter-hello-world 開始,我正在構建這個網站,該網站將由一個首頁組成,頂部有一個英雄,包含介紹信息。 右下角,我打算插入一些內容(我還不確定是什么),這個<Header />
出現在滾動條上。 對於那部分,我打算使用 Headroom.js,它已經在站點中運行了。 問題是我只需要在 Hero 組件的底部接觸到視口的頂部后才觸發它。 而這只會發生在台式機和筆記本電腦上。 在移動設備上,我打算將其設為固定導航欄。
無論如何,現在,這就是我對 Layout.js 所擁有的
import React from "react"
import PropTypes from "prop-types"
import { useStaticQuery, graphql } from "gatsby"
import Hero from "./index/hero"
import Header from "./header"
import Headroom from "react-headroom"
const Layout = ({ children }) => {
const data = useStaticQuery(graphql`
query SiteTitleQuery {
site {
siteMetadata {
title
}
}
}
`)
function() getHeroSize {
var heroHeight = Hero.clientHeight;
}
return (
<>
<Hero siteTitle={data.site.siteMetadata.title} ref="inner" />
<div className={"container mx-auto"}>
<Headroom pinStart={heroHeight}>
<Header siteTitle={data.site.siteMetadata.title} />
</Headroom>
<div
//style={{
// margin: `0 auto`,
// maxWidth: 960,
// padding: `0px 1.0875rem 1.45rem`,
// paddingTop: 0,
//}}
>
<main>{children}</main>
<footer>
© {new Date().getFullYear()}, Construído com
{` `}
<a href="https://www.gatsbyjs.org">Gatsby</a>
</footer>
</div>
</div>
</>
)
}
Layout.propTypes = {
children: PropTypes.node.isRequired,
}
export default Layout
上面的函數 getHeroSize 更像是我在想什么的意圖展示。 它真的行不通。
我正在使用 Tailwind CSS 並使用 gatsby-source-trello 從 Trello 采購一些內容。 還不確定如何制作這個 Layout.js,但這是我從一些測試中得到的結果,到目前為止效果很好。 我知道在 gatsby-node.js 中會有一些工作要做,但我相信這個標題會出現在我創建的任何其他頁面中,所以。
任何想法、建議或文檔鏈接都將得到真正的認可。 提前致謝!
你的Hero
組件需要使用forwardRef
將ref
傳遞給最近的 React 元素:
const Hero = React.forwardRef((props, ref) =>
<div ref={ref}>
{props.title}
</div>
然后您需要在Layout
創建一個 ref 並將其傳遞給Hero
:
import React, { useRef } from "react"
const Layout = ({ children }) => {
const heroRef = useRef()
// ...
return (
<>
<Hero title={data.site.siteMetadata.title} ref={heroRef} />
{/* ... */}
</>
)
}
最后,您需要使用鈎子來測量heroRef.current
元素的實際高度。 這是我使用的一種:
import { useEffect, useState } from "react"
import debounce from "lodash/debounce"
export default (ref, ttl = 100) => {
const [dimensions, setDimensions] = useState()
useEffect(() => {
if (!ref.current) return
const measure = debounce(() => {
if (ref.current) {
setDimensions(ref.current.getBoundingClientRect())
}
}, ttl)
measure()
window.addEventListener("resize", measure)
return () => {
window.removeEventListener("resize", measure)
}
}, [ref, ttl])
return dimensions
}
以下是將其添加到Layout
:
import useElementDimensions from "hooks/useElementDimensions"
const Layout = ({ children }) => {
const heroRef = useRef()
const heroDims = useElementDimensions(heroRef) || { top: 0, height: 0 }
const heroBottom = heroDims.top + heroDims.height
return (
<Headroom pinStart={heroBottom}>
<Header siteTitle={data.site.siteMetadata.title} />
</Headroom>
)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.