React条件渲染数据报错:Gatsby项目处理null描述字段问题
解决Gatsby中Contentful空MDX字段渲染报错问题
问题根源
- 当Contentful中的
description字段为null时,直接访问pic.description.childMdx.body会触发Cannot read property 'childMdx' of null错误——null对象不存在childMdx属性。 - 错误地将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"}}>← 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
相关产品推荐
相关产品推荐

