You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React条件渲染数据报错:Gatsby项目处理null描述字段问题

解决Gatsby中Contentful空MDX字段渲染报错问题

问题根源

  1. 当Contentful中的description字段为null时,直接访问pic.description.childMdx.body会触发Cannot read property 'childMdx' of null错误——null对象不存在childMdx属性。
  2. 错误地将React元素(<p>.</p>)传入MDXRenderer组件,该组件仅支持渲染MDX格式的文本内容,无法直接解析React节点。

解决方案

1. 核心修复:完善前端条件判断

使用可选链操作符(?.)逐层校验字段是否存在,同时将条件判断移到MDXRenderer外部,确保只有存在有效MDX内容时才渲染该组件,否则显示替代文本。

修改后的关键代码片段:

<p className="pt-4">
  {pic.description?.childMdx?.body ? (
    <MDXProvider>
      <MDXRenderer>{pic.description.childMdx.body}</MDXRenderer>
    </MDXProvider>
  ) : (
    <p>.</p>
  )}
</p>

2. (可选)从数据层面处理空值

在GraphQL查询中为body字段设置默认空字符串,减少前端判断层级:

export const query = graphql`
  query($slug: String!) {
      allContentfulMalerei(filter: { slug: { eq: $slug } }) {
        nodes {
          year
          width
          title
          description {
            childMdx {
              body @default(value: "")
            }
          }
          image {
            gatsbyImageData(width: 600, placeholder: BLURRED)
          }
        }
      }
    }
`

完整修改后的组件代码

import React from 'react'
import { graphql, Link } from 'gatsby'
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import Layout from '../components/Layout'

import { MDXProvider } from "@mdx-js/react"
import MDXRenderer from "gatsby-plugin-mdx/mdx-renderer"


export default function MalreiTemplate({ data }) {
    const picture = data.allContentfulMalerei.nodes

    return (
        <Layout>
          {picture.map(pic => {
              const image = getImage(pic.image)
              return(
              <div key={pic.slug} className="mb-3">
                <div className="pt-3 d-flex justify-content-between">
                  <span><Link to="/malerei" style={{textDecoration: "none", color: "#589AAD"}}>&#8592; zurück</Link></span>
                </div>
                  <hr />
                <div className="artwork-detail-container d-flex">
                  <div className="artwork-detail-image-container">
                    <GatsbyImage image={image}/>
                  </div>
                  <div className="artwork-detail-text">
                    <h3>{pic.title}, {pic.year}</h3>
                    <h4>{pic.type}</h4>
                    <p className="pt-4">
                      {pic.description?.childMdx?.body ? (
                        <MDXProvider>
                          <MDXRenderer>{pic.description.childMdx.body}</MDXRenderer>
                        </MDXProvider>
                      ) : (
                        <p>.</p>
                      )}
                    </p>
                  </div>
                </div>
                <hr/>
              </div>
          )})}
        </Layout>
    )
}


export const query = graphql`
  query($slug: String!) {
      allContentfulMalerei(filter: { slug: { eq: $slug } }) {
        nodes {
          year
          width
          title
          description {
            childMdx {
              body
            }
          }
          image {
            gatsbyImageData(width: 600, placeholder: BLURRED)
          }
        }
      }
    }
`

说明

  • 可选链操作符?.会在字段为null/undefined时自动停止访问,避免抛出错误。
  • 将React替代元素移到MDXRenderer外部,符合组件使用规范——MDXRenderer仅负责渲染MDX编译后的内容。

内容的提问来源于stack exchange,提问作者Hanna Rosenfeld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:31:06