【问题标题】:Conditional Rendering of Layout in GatsbyGatsby 中布局的条件渲染
【发布时间】:2020-07-02 21:03:39
【问题描述】:

当前行为

嗨。我正在使用 Gatsby,我的布局组件(包含页眉和页脚)放置在 gatsby-browser.jsgatsby-ssr.js' wrapPageElement 中。但是,这样做会在每个页面上呈现布局。我已将布局组件放在 gatsby-browser 和 gatsby-ssr 中,因为我的标题中有动态内容 - 如果用户通过身份验证,它会显示用户的电子邮件和导航链接

期望的行为

我希望我的索引页面不要被布局包裹,因为它只是一个静态页面,仅用于设计,没有任何动态内容

从今以后,有什么办法可以在我的 index.js 中不使用 Layout 吗?谢谢

gatsby-ssr.js & gatsby-browser.js

export const wrapPageElement = ({ element, props }) => {
      return <Layout {...props}>{element}</Layout>
    }

index.js

// 由于布局组件位于 gatsby-ssr 和 gatsby-browser.js 中,因此仍在渲染包含页眉和页脚的布局

import React from "react"
import { Link } from "gatsby"

import { Container } from "../components/common"
import SEO from "../components/seo"

const IndexPage = props => {
  return (
    <Container>
      <SEO title="Home" />
      <div>
        <Link to="/account">Go to your account</Link>
      </div>
    </Container>
  )
}

export default IndexPage

【问题讨论】:

    标签: gatsby


    【解决方案1】:

    从 gatsby-ssr 和 gatsby-browser.js 中删除布局。而是将其放在所有pages 组件中。

    您的index 应如下所示:

    const IndexPage = props => {
      return (
        <Layout {...props}>
          <Container>
            <SEO title="Home" />
            <div>
              <Link to="/account">Go to your account</Link>
            </div>
          </Container>
        </Layout>
      )
    }
    

    您应该只将组件放在每个页面上您想要的 gatsby-ssr 和 gatsby-browser.js 中,例如 react-helmet 或页面范围的 React 上下文。

    您不希望布局显示在索引上,因此您不能将其放在 gatsby-ssr 和 gatsby-browser.js 中。

    【讨论】:

    • 感谢@EliteRaceElephant。我遇到了一个教程,该教程将布局放入 gatsby-ssr 和 gatsby-browser 以避免在使用动态内容时出现闪烁,因此我在玩弄将布局放入 gatsby-ssr 和 gatsby-browser 的可能性
    【解决方案2】:

    编辑 25aug2021

    我最初建议检查“children.key”,当您实际构建您的网站时,它不起作用。相反,“children.props.location.pathname”适用于 SSR 和非 SSR。这是创建构建时“children”的示例输出:

    {
        "key": null,
        "ref": null,
        "props": {
            "path": "/*",
            "*": "share-your-story",
            "uri": "/",
            "location": {
                "pathname": "/share-your-story",
                "search": "",
                "hash": ""
            },
            "pageContext": {
                "slug": "share - your - story "},
                "params":{}
        },
        "_owner":null
    }
    

    我在下面更新了我的答案。

    对于仍在寻找其他解决方案的任何人:

    这可以通过检查“children.props.location.pathname”的值来获取您传递给每个页面的布局组件的元素/子项。该值包含该页面的路径。

    因此,在您的 Layout 组件中,您可以简单地检查它被调用的页面路径,然后确定要呈现的内容。

    例如我不想在带有路径“/no_layout”的页面上渲染“导航”和“页脚”,那么我将在 Layout.jsx 中执行此操作:

    const Layout = ({ children }) => {
      // Conditionally don't show top and bottom nav
      if (children.props.location.pathname === '/no_layout') {
        return <>{children}</>
      }
    
      return (
        <>
          <Navigation />
          {children}
          <Footer />
        </>
      )
    }
    
    export default Layout
    

    或者,如果您有多个页面/路径要从常规布局中排除,并且可能具有全屏布局,那么您可以将它们放在一个列表中并检查当前路径是否存在:

    const fullScreenPaths = [
      '/no_layout',
      '/never_layout',
      '/skip_layout',
      '/nope_layout',
      '/hellno_layout',
    ]
    
    const Layout = ({ children }) => {
      // Conditionally don't show top and bottom nav
      if (fullScreenPaths.includes(children.props.location.pathname)) {
        return <>{children}</>
      }
    
      return (
        <>
          <Navigation />
          {children}
          <Footer />
        </>
      )
    }
    
    export default Layout
    

    感谢this old comment on github 让我走上正轨。

    如果您不完全理解我所说的“children.props.location.pathname”是什么意思,那么只需:

    console.log(children)
    

    查看可用于渲染布局的所有值。

    【讨论】:

      猜你喜欢
      • 2021-08-24
      • 2020-10-22
      • 1970-01-01
      • 2011-02-05
      • 2021-03-19
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-02-24
      相关资源
      最近更新 更多