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

在Gatsby中如何将Staticman表单提交筛选至对应页面?

解决Gatsby中评论数据筛选时的Cannot read property 'edges' of undefined错误

我来帮你排查这个问题——你遇到的这个错误,通常是因为组件在数据加载完成前就尝试访问allReviewsYaml.edges,或者你的页面查询没有正确接收$slug参数、评论数据的fields.slug字段未正确生成,导致查询返回的allReviewsYaml为undefined。下面分步骤帮你解决:

1. 确认页面查询的参数传递是否正确

首先要明确:带变量的GraphQL查询只能用在页面组件中(src/pages下的文件,或通过gatsby-node.js动态生成的页面),StaticQuery不支持变量传递。

如果是通过gatsby-node.js生成动态页面,务必确保在createPage时把slug参数传入context:

// gatsby-node.js 示例代码
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  // 先获取所有房源数据
  const propertyResult = await graphql(`
    query {
      allPropertyYaml {
        edges {
          node {
            listing_id
          }
        }
      }
    }
  `);

  // 为每个房源生成详情页
  propertyResult.data.allPropertyYaml.edges.forEach(({ node }) => {
    createPage({
      path: `/property/${node.listing_id}`,
      component: require.resolve("./src/templates/property-review-page.js"),
      context: {
        slug: node.listing_id, // 关键:传递slug参数给页面查询
      },
    });
  });
};

如果是src/pages下的动态路由页面(比如[slug].js),Gatsby会自动把URL中的参数作为slug传入查询,这一步无需额外配置。

2. 确保评论YAML文件的fields.slug字段正确生成

你的查询依赖fields.slug来筛选对应房源的评论,所以必须通过gatsby-node.js的onCreateNode API为每个评论文件添加这个字段:

// gatsby-node.js 示例代码
exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions;
  // 只处理评论YAML节点
  if (node.internal.type === "ReviewsYaml") {
    // 从文件路径中提取listing_id
    const parentFile = getNode(node.parent);
    // 你的文件路径是src/data/review/property-[listing_id]/xxx.yml,拆分路径获取房源ID
    const propertyDir = parentFile.relativePath.split("/")[1];
    const listingId = propertyDir.replace("property-", "");
    
    createNodeField({
      node,
      name: "slug",
      value: listingId,
    });
  }
};

这一步如果出错,查询的filter条件会匹配不到任何数据,直接导致allReviewsYaml返回undefined。

3. 在组件中添加空值检查并正确访问数据

Gatsby在构建或客户端渲染时,数据可能还未完全加载,所以必须先做空值判断,再访问edges:

import React from "react";
import { graphql } from "gatsby";

const PropertyReviewPage = ({ data }) => {
  // 用可选链操作符避免访问undefined属性,也可以用条件判断
  const reviews = data.allReviewsYaml?.edges || [];
  const property = data.property;

  // 房源数据未加载时显示加载状态
  if (!property) {
    return <div>Loading...</div>;
  }

  return (
    <div className="property-page">
      <h1>房源ID: {property.listing_id}</h1>
      <p>{property.description}</p>
      
      <h2>用户评论</h2>
      {reviews.length === 0 ? (
        <p>暂无评论,快来留下第一条吧~</p>
      ) : (
        reviews.map(({ node }) => (
          <div key={`${node.listing_id}-${node.date}`} className="review-card">
            <h3>评论人:{node.name}</h3>
            <p>{node.review}</p>
          </div>
        ))
      )}
    </div>
  );
};

// 注意:调整property的类型名称(如果是YAML文件,Gatsby会自动转为驼峰式,比如propertyYaml)
export const query = graphql`
  query($slug: String!) {
    property: propertyYaml(listing_id: { eq: $slug }) {
      description
      listing_id
    }
    allReviewsYaml(
      filter: { fields: { slug: { eq: $slug } } }
      sort: { fields: date, order: DESC }
    ) {
      edges {
        node {
          name
          review
          listing_id
          date
        }
      }
    }
  }
`;

export default PropertyReviewPage;

4. 验证GraphQL查询的正确性

在GraphiQL中测试时,务必传入和页面context一致的$slug参数(比如{"slug": "123"}),确认查询能返回预期的allReviewsYaml数据。如果查询在GraphiQL中正常,但页面报错,大概率是参数传递或空值检查的问题。

按照以上步骤逐一排查,应该就能解决这个错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:47:55