在下面的代码中,我遇到了收到 400 BAD REQUEST 并且 pageData 无法加载的问题。当我简单地删除 GridText 模块时,代码工作正常。 ChatGPT 和我已经没有主意了。我希望有人能帮忙.. 我添加了 GridText,就像我为其他模块所做的那样,当我在 env 链接中测试它时,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";
// Define the structure of the page data
interface PageData {
title: string;
modules: Array<
{
identifier: string;
} & (TextImageFields | HeroFields | GridTourFields | GridTextFields)
>;
}
// Define the expected shape of the GraphQL response
interface GraphQLResponse {
page: PageData;
}
// Initialize the GraphQL Client with the endpoint from Vite's environment variable
const graphConnect = new GraphQLClient(import.meta.env.VITE_ENDPOINT);
// GraphQL query to fetch page data by slug
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 }>(); // Get slug from URL params
const [pageData, setPageData] = useState<PageData | null>(null); // State to hold page data
const [navigationData, setNavigationData] =
useState<NavigationResponse | null>(null); // State for navigation data
const [footerData, setFooterData] = useState<FooterResponse | null>(null); // State for footer data
const [loading, setLoading] = useState(true); // Loading state
const [error, setError] = useState<string | null>(null); // Error state
useEffect(() => {
const fetchData = async () => {
setLoading(true); // Start loading
setError(null); // Reset error state
try {
// Fetch page data
const response = await graphConnect.request<GraphQLResponse>(
pageQuery,
{
slug,
}
);
if (!response.page) {
throw new Error(`No page found for slug: ${slug}`);
}
setPageData(response.page); // Set page data
// Fetch navigation data
const navigationResponse =
await graphConnect.request<NavigationResponse>(navigationQuery);
setNavigationData(navigationResponse);
// Fetch footer data
const footerResponse = await graphConnect.request<FooterResponse>(
footerQuery
);
setFooterData(footerResponse);
} catch (err: any) {
// Log GraphQL specific error response if available
if (err.response && err.response.errors) {
console.error("GraphQL Response Error Details:", err.response.errors);
} else {
console.error("Unexpected error:", err);
}
setError("Failed to load data."); // Set error message
} finally {
setLoading(false); // End loading
}
};
fetchData();
}, [slug]); // Run effect when slug changes
if (loading) {
return <div>Loading...</div>; // Show loading state
}
if (error) {
return <div>{error}</div>; // Show error message
}
if (!pageData) {
return <NotFound />; // Show 404 if no page data
}
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索引.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 片段.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":"\n query ($slug: String!) {\n page(where: { slug: $slug }) {\n title\n modules {\n ... on TextImage {\n ...TextImageFields\n }\n ... on Hero {\n ...HeroFields\n }\n ... on GridTour {\n ...GridTourFields\n }\n ... on GridText {\n ...GridTextFields\n }\n }\n }\n }\n \n fragment TextImageFields on TextImage {\n id\n identifier\n headline\n image {\n url\n alt\n }\n paragraph {\n text {\n html\n }\n }\n }\n\n \n fragment HeroFields on Hero {\n id\n identifier\n imageLarge {\n url\n alt\n }\n links {\n ...PagelinkFields\n ...URLFields\n }\n paragraph {\n text {\n html\n }\n }\n imageSmall {\n url\n alt\n }\n headline {\n size\n text\n }\n }\n \n fragment PagelinkFields on Pagelink {\n identifier\n id\n text\n page {\n slug\n }\n }\n\n \n fragment URLFields on URL {\n identifier\n id\n url\n text\n }\n\n\n \n fragment GridTourFields on GridTour {\n id\n identifier\n headline {\n size\n text\n }\n gridTourSection {\n id\n headline\n guidedTour {\n slug\n id\n bookingForm\n coverImage {\n url\n alt\n }\n description\n distance\n duration\n highlights\n images {\n id\n url\n alt\n width\n height\n }\n title\n }\n }\n }\n\n \n fragment GridTextFields on GridText {\n id\n identifier\n headline {\n size\n text\n }\n }\n\n","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)
当我查看错误消息时
Error fetching data: _ClientError: GraphQL Error (Code: 400)
,这告诉我这是一个 GraphQL 查询语法错误。
这意味着您发送的 GraphQL 查询有问题。不确定它与 GridText 有关。
我建议将您发送的 GraphQL 查询与 React.js 代码隔离开来,并确保查询正确。 合适的工具是 GraphQL 游乐场,例如如果您使用 Apollo 为您的 GraphQL 服务器提供服务,我所说的将位于此地址 http://localhost:4000/graphql
这将允许您迭代查询语法并消除问题根源。