如何使用GatsbyJS根据路线渲染组件?

时间:2019-08-10 14:54:01

标签: javascript reactjs react-router jsx gatsby

我正在使用GatsbyJS,并且尝试根据URL的路由呈现不同的header

示例:

mydomain.com/ =>应该呈现HeaderLanding

mydomain.com/blog =>应该呈现HeaderMain

有人知道根据layout.js文件中的路径创建条件渲染以显示组件的正确方法吗?

感谢您的支持。

// layout.js

import React from "react"
import PropTypes from "prop-types"
import HeaderLanding from "./header-landing"
import HeaderMain from "./header-main"
import Footer from "./footer"

const Layout = ({ children }) => {
  return (
    <>
      <Header/>
      <div className="content-wrapper">
        <main>{children}</main>
      </div>
      <Footer/>
    </>
  )
}

export default Layout

2 个答案:

答案 0 :(得分:2)

您可以使用withRouter HOC的location对象。

import { withRouter } from 'react-router-dom';

const Layout = ({ children, location }) => {

  return (
    <>
      {location.pathname.split('/')[1] ==="blog" ? <HeaderMain /> : <HeaderLanding /> }
      <div className="content-wrapper">
        <main>{children}</main>
      </div>
      <Footer/>
    </>
  )
}

export default withRouter(Layout)

更新

盖茨比v2 已将路由器从react-router切换为@reach/router

docs

  

在v1中,布局组件可以访问历史记录,位置和匹配道具。在v2中,只有页面可以访问这些道具。如果您在布局组件中需要这些道具,请从页面传递它们。

因此,您的Layout组件应该是

const Layout = ({ children, location }) => {

  return (
    <>
      {location.pathname.split('/')[1] ==="blog" ? <HeaderMain /> : <HeaderLanding /> }
      <div className="content-wrapper">
        <main>{children}</main>
      </div>
      <Footer/>
    </>
  )
}

export default Layout

您的Page组件应该是(仅为示例)

import React from "react"
import Layout from "../components/layout"
export default props => (
  <Layout location={props.location}> //Pass location here
    <div>Hello World</div>
  </Layout>
)

或者,您可以使用Location

  

通常,您只能访问“路线组件”中的位置,“位置”通过子渲染道具在应用程序中的任何位置提供位置。

<Location>
  {props => {
    props.location
    props.navigate
  }}
</Location>

// usually folks use some destructuring
<Location>
  {({ location })=> {
    // ...
  }}
</Location>

答案 1 :(得分:2)

@ ravibagul91回答的内容差不多,但是Gatsby不使用react-router-dom

如果Layout是页面组件,则盖茨比将为其传递location道具。您可以提取location.pathname并在其中应用逻辑

const Layout = ({ children, location }) => {
  const isMain = location.pathname === 'your-path'

  return (
    <>
      { isMain ? <HeaderMain> : <HeaderLanding> }
      <div className="content-wrapper">
        <main>{children}</main>
      </div>
      <Footer/>
    </>
  )
}

export default Layout

如果Layout不是页面组件,则可以从Location导入HOC @reach/router

import { Location } from '@reach/router' // gatsby's dep

const Layout = ({ children }) => {
  return (
    <Location>
       {({ location }) => (
         ...
       )}
    </Location>

  )
}

或者将location道具从Gatsby页面组件传递到每个页面的该组件:

import Layout from '../components/layout'

export default ({ location }) => (
  <Layout location={location}>
    ...
  </Layout>
)