Vite React集成HygraphCMS出现400 Bad Request错误求助
问题:添加GridText模块后GraphQL请求返回400错误,移除则恢复正常
我在Vite React项目中遇到了一个问题:当添加GridText模块后,页面数据(pageData)无法加载,返回400 BAD REQUEST错误;但只要移除GridText相关代码,请求就能正常运行。我是按照其他模块的实现方式来添加GridText的,并且单独在环境链接中测试API时,响应是正常的。
以下是相关代码和完整错误信息:
[slug].tsx
import React, { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import { GraphQLClient, gql } from "graphql-request"; import NotFound from "./NotFound"; import "../styles/index.css"; import Nav from "../modules/Nav/index"; import { navigationQuery, NavigationResponse } from "../modules/Nav/fragment"; import Footer from "../modules/Footer/index"; import { footerQuery, FooterResponse } from "../modules/Footer/fragment"; import TextImage from "../modules/TextImage/index"; import { TEXT_IMAGE_FRAGMENT, TextImageFields, } from "../modules/TextImage/fragment"; import Hero from "../modules/Hero/index"; import { HERO_FRAGMENT, HeroFields } from "../modules/Hero/fragment"; import GridTour from "../modules/GridTour/index"; import { GRID_TOUR_FRAGMENT, GridTourFields, } from "../modules/GridTour/fragment"; import GridText from "../modules/GridText/index"; import { GRID_TEXT_FRAGMENT, GridTextFields, } from "../modules/GridText/fragment"; // 定义页面数据结构 interface PageData { title: string; modules: Array< { identifier: string; } & (TextImageFields | HeroFields | GridTourFields | GridTextFields) >; } // 定义GraphQL响应的预期结构 interface GraphQLResponse { page: PageData; } // 使用Vite环境变量初始化GraphQL客户端 const graphConnect = new GraphQLClient(import.meta.env.VITE_ENDPOINT); // 根据slug获取页面数据的GraphQL查询 const pageQuery = gql` query ($slug: String!) { page(where: { slug: $slug }) { title modules { ...TextImageFields ...HeroFields ...GridTourFields ...GridTextFields } } } } ${TEXT_IMAGE_FRAGMENT} ${HERO_FRAGMENT} ${GRID_TOUR_FRAGMENT} ${GRID_TEXT_FRAGMENT} `; const Page: React.FC = () => { const { slug } = useParams<{ slug: string }>(); // 从URL参数获取slug const [pageData, setPageData] = useState<PageData | null>(null); // 存储页面数据的状态 const [navigationData, setNavigationData] = useState<NavigationResponse | null>(null); // 导航数据状态 const [footerData, setFooterData] = useState<FooterResponse | null>(null); // 页脚数据状态 const [loading, setLoading] = useState(true); // 加载状态 const [error, setError] = useState<string | null>(null); // 错误状态 useEffect(() => { const fetchData = async () => { setLoading(true); // 开始加载 setError(null); // 重置错误状态 try { // 获取页面数据 const response = await graphConnect.request<GraphQLResponse>( pageQuery, { slug, } ); if (!response.page) { throw new Error(`未找到slug为${slug}的页面`); } setPageData(response.page); // 设置页面数据 // 获取导航数据 const navigationResponse = await graphConnect.request<NavigationResponse>(navigationQuery); setNavigationData(navigationResponse); // 获取页脚数据 const footerResponse = await graphConnect.request<FooterResponse>( footerQuery ); setFooterData(footerResponse); } catch (err: any) { // 如果有GraphQL特定错误响应则打印详情 if (err.response && err.response.errors) { console.error("GraphQL响应错误详情:", err.response.errors); } else { console.error("意外错误:", err); } setError("加载数据失败"); // 设置错误提示 } finally { setLoading(false); // 结束加载 } }; fetchData(); }, [slug]); // 当slug变化时重新执行 if (loading) { return <div>加载中...</div>; // 显示加载状态 } if (error) { return <div>{error}</div>; // 显示错误信息 } if (!pageData) { return <NotFound />; // 展示404页面 } return ( <> {navigationData && <Nav data={navigationData.navigation} />} <div className="relative top-16"> {pageData.modules.map((module) => { if (!module.id) { return null; } switch (module.identifier) { case "TextImage": return ( <TextImage key={module.id} data={module as TextImageFields} /> ); case "Hero": return <Hero key={module.id} data={module as HeroFields} />; case "GridTour": return ( <GridTour key={module.id} data={module as GridTourFields} /> ); case "GridText": return ( <GridText key={module.id} data={module as GridTextFields} /> ); default: return null; } })} </div> {footerData && <Footer data={footerData.footer} />} </> ); }; export default Page;
GridText/index.tsx
import React from "react"; interface HeadlineData { size: string; text: string; } interface GridTextProps { data: { headline?: HeadlineData | null; }; } const GridText: React.FC<GridTextProps> = ({ data }) => { return ( <div> <p>{data?.headline?.text}</p> </div> ); }; export default GridText;
GridText/fragment.ts
import { gql } from "graphql-request"; export const GRID_TEXT_FRAGMENT = gql` fragment GridTextFields on GridText { id identifier headline { size text } } `; export interface GridTextFields { id: string; identifier: string; headline: { size: string; text: string; } | null; }
完整错误信息
Error fetching data: _ClientError: GraphQL Error (Code: 400): {"response":{"status":400,"headers":{}},"request":{"query":" query ($slug: String!) { page(where: { slug: $slug }) { title modules { ... on TextImage { ...TextImageFields } ... on Hero { ...HeroFields } ... on GridTour { ...GridTourFields } ... on GridText { ...GridTextFields } } } } fragment TextImageFields on TextImage { id identifier headline image { url alt } paragraph { text { html } } } fragment HeroFields on Hero { id identifier imageLarge { url alt } links { ...PagelinkFields ...URLFields } paragraph { text { html } } imageSmall { url alt } headline { size text } } fragment PagelinkFields on Pagelink { identifier id text page { slug } } fragment URLFields on URL { identifier id url text } fragment GridTourFields on GridTour { id identifier headline { size text } gridTourSection { id headline guidedTour { slug id bookingForm coverImage { url alt } description distance duration highlights images { id url alt width height } title } } } fragment GridTextFields on GridText { id identifier headline { size text } } ","variables":{"slug":"home"}}} at runRequest (graphql-request.js?v=51386c9c:7767:12) at async GraphQLClient.request (graphql-request.js?v=51386c9c:7962:22) at async fetchData ([slug].tsx:91:26)
内容的提问来源于stack exchange,提问作者Maren S
相关产品推荐
相关产品推荐

