Reactjs “我该如何解决?”;TypeError:childImageSharp未定义;关于NetlifyCMS构建?

Reactjs “我该如何解决?”;TypeError:childImageSharp未定义;关于NetlifyCMS构建?,reactjs,graphql,gatsby,netlify,netlify-cms,Reactjs,Graphql,Gatsby,Netlify,Netlify Cms,我正在现有的盖茨比网站上建立一个简单的博客页面,我希望使用netlify cms的人能够上传一个博客文章的缩略图。我已经设法这样做,并找到它使用graphigl 现在我想将其设置到我的博客帖子页面: import React from "react" import { Link, graphql, useStaticQuery } from "gatsby" import Layout from "../components/layout/l

我正在现有的盖茨比网站上建立一个简单的博客页面,我希望使用netlify cms的人能够上传一个博客文章的缩略图。我已经设法这样做,并找到它使用graphigl

现在我想将其设置到我的博客帖子页面:

import React from "react"
import { Link, graphql, useStaticQuery } from "gatsby"

import Layout from "../components/layout/layout"

const Blog = () => {
  const data = useStaticQuery(graphql`
    query {
      allMarkdownRemark {
        edges {
          node {
            frontmatter {
              title
              date
              thumbnail {
                childImageSharp {
                  fluid(maxWidth: 400) {
                    src
                  }
                }
              }
            }
            fields {
              slug
            }
          }
        }
      }
    }
  `)

  return (
    <>
      <Layout>
        <main className="main">
          <div className="articles">
            <h1 className="articles__title">Articles</h1>
            {data.allMarkdownRemark.edges.map(edge => {
              return (
                <section className="articles__list">
                  <a className="articles__article">
                    <div className="articles__article-artwork">
                      <figure className="articles__article-artwork-wrapper">
                        {edge.node.frontmatter.thumbnail.childSharpImage.fluid.src}
                      </figure>
                    </div>
                    <h2 className="articles__article-title">
                      <Link to={`/blog/${edge.node.fields.slug}`}>
                        {edge.node.frontmatter.title}
                      </Link>
                    </h2>
                    <Link>
                      <p>{edge.node.frontmatter.date}</p>
                    </Link>
                    <div className="articles__article-description">
                      <p></p>
                    </div>
                    <span className="articles__article-more">Read more...</span>
                  </a>
                </section>
              )
            })}
          </div>
        </main>
      </Layout>
    </>
  )
}
export default Blog

gatsby-node.js

const path = require('path')

module.exports.onCreateNode = ({ node, actions }) => {
    const { createNodeField } = actions

    if (node.internal.type === "MarkdownRemark") {
        const slug = path.basename(node.fileAbsolutePath, '.md')

        createNodeField({
            node,
            name: 'slug',
            value: slug
        })
    }
}

module.exports.createPages = async ({ graphql, actions}) => {
    const { createPage } = actions
    const blogTemplate = path.resolve('./src/templates/blog.js')
    const res = await graphql(`
        query {
            allMarkdownRemark {
                edges {
                    node {
                        fields {
                            slug
                        }
                    }
                }
            }
        }
    `)

    res.data.allMarkdownRemark.edges.forEach((edge) => {
        createPage({
            component: blogTemplate,
            path: `/blog/${edge.node.fields.slug}`,
            context: {
                slug: edge.node.fields.slug
            }
        })
    })
}
gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `removed for work reasons`,
    description: `removed`,
    author: `removed`,
  },
  plugins: [
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-sass`,
    `gatsby-plugin-remove-serviceworker`,
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `img`,
        path: `${__dirname}/static/img`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `src`,
        path: `${__dirname}/src`,
      },
    },
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
      },
    },
    {
      resolve: 'gatsby-plugin-react-svg',
      options: {
        rule: {
          include: /assets/
        }
      }
    },
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images`,
              options: {
                maxWidth: 590,
              }
          },
          {
            resolve: `gatsby-plugin-netlify-cms-paths`,
            options: {
              cmsConfig: `/static/admin/config.yml`
            }
          }
        ]
      }
    },
    // this (optional) plugin enables Progressive Web App + Offline functionality
    // To learn more, visit: https://gatsby.dev/offline
    // `gatsby-plugin-offline`,
    `gatsby-plugin-netlify-cms`,
    `gatsby-plugin-netlify`,
  ],
}

老实说,我认为使用netlify cms在我现有的盖茨比网站上添加一个博客页面是轻而易举的事,但这是我尝试过的最困难的事情之一

非常感谢您的帮助


谢谢

我有几件事很奇怪

  • 您的查询无法工作(因此,中断代码),因为它找不到您的图像。将
    config.yml
    媒体路径更改为:

      media_folder: static/img
      public_folder: /img
    
    注意
    公用文件夹
    路径中的斜杠(
    /

    这是因为它是一个相对路径,必须以斜杠开始。(斜线部分加粗):

公用文件夹

此设置是必需的

public\u folder
选项指定文件所在的文件夹路径 通过媒体库上传的内容将被访问,相对于基地 已建场地的设计。对于由[file]或[image]窗口小部件控制的字段, 字段的值是通过将此路径前置到 所选文件的文件名。默认为介质文件夹的值, 带有一个开口
/
,如果其中一个开口尚未包含

   public_folder: "/images/uploads"
根据上述设置,如果用户使用图像小部件字段 调用
avatar
上载并选择名为
philosoraptor.png
的图像, 图像将保存到位于的存储库中
/static/img/philosoraptor.png
,以及 文件将设置为
/img/philosoraptor.png

您的
media\u文件夹
看起来不错

  • 标记内渲染图像的方式。按照您的方法,它将渲染带有图像路径的字符串,但是,您使用的是来自
    gatsby图像的sharp,而不是它。在一些试验中,我建议如下:

    <figure>
       <Img fluid={edges.node.frontmatter.thumbnail.childImageSharp.fluid}>
    </figure>
    
    请注意
    …GatsbyImageSharpFluid
    片段,以获取使用
    gatsby image
    所需的所有数据

  • 您使用的是
    staticQuery
    ,但您不需要它,因为您的所有数据都来自CMS。您应该使用来提高性能,但这会改变页面结构

    在Gatsby中创建动态页面的“标准”方法是,使用
    Gatsby node.js
    使用
    createPage
    API,将所需数据传递给模板(通常是
    id
    slug
    ),并使用该唯一数据检索博客/帖子信息

    您正在通过上下文传递
    slug
    ,但从未使用它:

      context: {
        slug: edge.node.fields.slug
      }
    
    此外,您正在使用静态查询再次循环浏览所有文章(
    allMarkdownRemark
    ),这是没有意义的,也是浪费时间和性能的

    您的
    博客
    模板应如下所示:

      import React from 'react'
      import { graphql } from 'gatsby'
    
      const Blog = ({data}) => {
        return (
          <div>
           Blog title is: {data.markdownRemark.frontmatter.title}
         </div>
       )
    }
    
    export const query = graphql`
       query BlogQuery($slug: String!) {
      query {
        markdownRemark(fields: { slug: { eq: $slug }}) {
              html
              frontmatter {
                title
                date
                thumbnail {
                  childImageSharp {
                    fluid(maxWidth: 400) {
                      ...GatsbyImageSharpFluid
                    }
                  }
                }
              }
              fields {
                slug
              }
            }
         }
       }
    `
    
    export default Blog
    
    从“React”导入React
    从“盖茨比”导入{graphql}
    const Blog=({data})=>{
    返回(
    博客标题为:{data.markdownRemark.frontmatter.title}
    )
    }
    export const query=graphql`
    查询BlogQuery($slug:String!){
    质疑{
    markdownRemark(字段:{slug:{eq:$slug}}){
    html
    前沿物质{
    标题
    日期
    缩略图{
    childImageSharp{
    流体(最大宽度:400){
    …盖茨比磁流体
    }
    }
    }
    }
    田地{
    鼻涕虫
    }
    }
    }
    }
    `
    导出默认博客
    
    请注意,您正在将slug(
    $slug
    )作为必需参数(
    String!
    )传递,因此页面查询不能为null。之后,您将筛选标记节点(
    markdownmark
    ),以获得与您在
    gatsby node.js
    文件中传递的上下文匹配的节点。换句话说,在这种情况下,您拥有每个帖子的数据

    还要注意,您可能需要更改查询以匹配您的数据结构,我在不知道字段的情况下从头发布了它。使用
    localhost:8000/\uuuuuu graphql
    (graphql游乐场)检查它。您的片段不会在那个里工作,因为它是GraphQL的一个限制,但它会在您的代码上工作,所以避免在那个里使用它,但要在代码中保留它


谢谢你,伙计。所以这个页面是我的博客文章页面,我为实际的个人文章制作了一个模板页面,在这里我没有使用staticQuery,而是使用just query和slug,这是应该通过的地方。我为你做了一些改变,但我仍然无法工作。现在我在“File”类型上得到“cannotqueryfield”childSharpImage。这太令人困惑了!抱歉把它改成了夏普。修复了输入错误,现在我又回到了“TypeError:无法读取未定义的'childImageSharp'属性”实际上,我能够在我的个人博客模板上使用图像,但在上面的博客文章页面上没有运气。静态错误TypeError:无法读取null的属性“childImageSharp”
  context: {
    slug: edge.node.fields.slug
  }
  import React from 'react'
  import { graphql } from 'gatsby'

  const Blog = ({data}) => {
    return (
      <div>
       Blog title is: {data.markdownRemark.frontmatter.title}
     </div>
   )
}

export const query = graphql`
   query BlogQuery($slug: String!) {
  query {
    markdownRemark(fields: { slug: { eq: $slug }}) {
          html
          frontmatter {
            title
            date
            thumbnail {
              childImageSharp {
                fluid(maxWidth: 400) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
          fields {
            slug
          }
        }
     }
   }
`

export default Blog