在 React Component 中根据页面名称渲染图像

Render image based on page name in React Component

我正在从 Contentful 中提取一张图像,该图像应该放入横​​幅组件中。 我网站的每个页面都应该有一个横幅。 在 Contentful 中,我为横幅图像的内容模型提供了一个引用页面名称的 slug。 现在,在我的 Gatsby 项目中,我创建了一个组件,并在其中使用了一个静态查询 returns slug(页面名称)。 在每个单独的页面中使用横幅组件,我想将页面名称与 slug 相匹配。例如,当我在页面 'malerei' 中时,带有 'malerei' slug 的图像(参见下面第二个代码片段中 MalereiPage 的示例)应该在组件中呈现。 我不确定如何实现这一点,但希望能对此有所帮助。

我的组件:

import React from 'react'
import { StaticQuery, graphql } from 'gatsby'


function Banner ({ data, props }) {
    return (
        <>
        <StaticQuery
            query={graphql`
              query BannerQuery {
                allContentfulBannerImage {
                    nodes {
                        slug
                        image {
                          id
                          resize(width: 1200) {
                            width
                            height
                            src
                          }
                        }
                    }
                 }
              }
          `}
          render={data => {

              return(
                <div>
                  {data.allContentfulBannerImage.nodes.map((image) => {

                        return (
                            <div key={image.slug}>
                                <img className="mb-5" src={image.image.resize.src} style={{float: "left", width: "100%", height: "90vh", objectFit: "cover"}}/>
                            </div>
                        )
                    })}

                </div>
              )}}
        />
            </>
    )
}


export default Banner

页面中使用 <Banner /> 的示例:

import React from 'react'
import Layout from '../components/Layout'
import Banner from '../components/Banner'


const MalereiPage = () => (
    <Layout>
        <Banner/>
    </Layout>
)



export default MalereiPage

我认为你最好的选择是使用 page query rather than a static query 因为你的横幅图片只会被获取一次,而不是每次你想要呈现一个新页面时。

也就是说,如果每个横幅图像都通过 slug 链接到每个页面,您可以创建一个特定的页面查询,通过这个 slug 过滤以获取您的数据。

类似于:

const MalereiPage = ( { data } ) => (
    <Layout>
      <Banner image={data.allContentfulBannerImage.nodes}/>
    </Layout>
)

export const query = graphql`
query getMalereiContent {
  allContentfulBannerImage(filter: {slug: {eq: "malerei"}}) {
    nodes {
      slug
      image {
        id
        resize(width: 1200) {
          width
          height
          src
        }
      }
    }
  }
}
`

export default MalereiPage

并且:

function Banner(props) {
  const image = props.image;
  console.log(image);
  image.map((img) => {
    console.log(img.image);
  });
  return (
    <div>
      {image.map((img) => {
        return (
          <div key={img.slug}>
            <img
              className="mb-5"
              src={img.image.resize.src}
              style={{
                float: "left",
                width: "100%",
                height: "90vh",
                objectFit: "cover",
              }}
            />
          </div>
        );
      })}
    </div>
  );
}

export default Banner;

注意:请记住,在不知道您的架构或数据结构的情况下,这是一个近似值。在 localhost:8000/___graphql

处测试查询

这个想法依赖于使用该页面的已知 slug 过滤页面查询。在那里,您可以获取该特定页面的所有页面数据,包括横幅图像。

此时,您只需将图像节点传递给您的Banner组件即可直接渲染资产,而无需使用StaticQuery

感谢 Ferran Buireu 的热心帮助。这帮助我解决了我的问题。 这是我的工作代码:

页面(查询):

import React from 'react'
import {graphql} from 'gatsby'

import Layout from '../components/Layout'
import Banner from '../components/Banner'


const MalereiPage = ( { data } ) => (
    <Layout>
      <Banner image={data.allContentfulBannerImage.nodes}/>
    </Layout>
)

export const query = graphql`
query getMalereiContent {
  allContentfulBannerImage(filter: {slug: {eq: "malerei"}}) {
    nodes {
      slug
      image {
        id
        resize(width: 1200) {
          width
          height
          src
        }
      }
    }
  }
}
`


export default MalereiPage

横幅组件:

import React from 'react'
import { StaticQuery, graphql } from 'gatsby'



function Banner (props) {
    const image = props.image
    console.log(image)
    image.map(img => {
        console.log(img.image)
    })
    return(
        <div>
        {image.map(img => {
            return(
                  <div key={img.slug}>
                    <img className="mb-5" src={img.image.resize.src} style={{float: "left", width: "100%", height: "90vh", objectFit: "cover"}}/>
                  </div>
            )
        })}
        </div>
    )}


export default Banner

再次感谢! :)