簡體   English   中英

如何在 React 中獲取組件高度以觸發 Headroom?

[英]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組件需要使用forwardRefref傳遞給最近的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM