@apollo/client
的useQuery
,展示如何在前端客戶端查詢模擬數據我們首先將設置apollo client給抽取出來,並放在apps\iron-ecommerce-next\libs\graphql\apollo-client.ts
:
import { mockedCartItems, mockedProducts } from "./graphql-mocks";
import schema from "./schema.graphql";
import { ApolloLink, HttpLink } from "@apollo/client";
import {
NextSSRApolloClient,
NextSSRInMemoryCache,
SSRMultipartLink
} from "@apollo/experimental-nextjs-app-support/ssr";
const mockedCache = new NextSSRInMemoryCache({
typePolicies: {
Query: {
fields: {
getProducts: {
read() {
return mockedProducts();
}
},
getCartItems: {
read() {
return mockedCartItems();
}
}
}
}
}
});
export const makeGraphqlClient = () => {
const httpLink = new HttpLink({
uri: "http://localhost:4200/graphql"
});
return new NextSSRApolloClient({
cache: process.env.NODE_ENV === "development" ? mockedCache : new NextSSRInMemoryCache(),
link:
typeof window === "undefined"
? ApolloLink.from([
new SSRMultipartLink({
stripDefer: true
}),
httpLink
])
: httpLink,
typeDefs: schema
});
};
由於我們import了graphql的檔案格式,我們需要定義types。(Link)我們創建graphql.d.ts在apps\iron-ecommerce-next\typings\graphql.d.ts
:
declare module "*.graphql" {
import { DocumentNode } from "graphql";
const Schema: DocumentNode;
export = Schema;
}
並修改我們的AppProvider,打開apps\iron-ecommerce-next\app\app-provider.tsx
並修改
"use client";
import {
ApolloNextAppProvider
} from "@apollo/experimental-nextjs-app-support/ssr";
import { CSSProvider } from "@master/css.react";
import { Theme } from "@radix-ui/themes";
import config from "master.css";
import { RecoilRoot } from "recoil";
import { makeGraphqlClient } from "../libs/graphql/apollo-client";
export default function AppProvider({ children }: { children: React.ReactNode }) {
return (
<ApolloNextAppProvider makeClient={makeGraphqlClient}>
<RecoilRoot>
<Theme>
<CSSProvider config={config}>{children}</CSSProvider>
</Theme>
</RecoilRoot>
</ApolloNextAppProvider>
);
}
接著我們創建apps\iron-ecommerce-next\libs\graphql\graphql-mocks.ts
:
import { makeVar } from "@apollo/client";
import { faker } from "@faker-js/faker";
export const mockedProducts = makeVar(
Array(10)
.fill(0)
.map(() => ({
id: faker.datatype.uuid(),
name: faker.commerce.productName(),
price: parseFloat(faker.commerce.price()),
description: faker.commerce.productDescription(),
imageUrl: faker.image.url()
}))
);
export const mockedCartItems = makeVar(
Array(10)
.fill(0)
.map(() => ({
productId: faker.string.uuid(),
productName: faker.commerce.productName(),
price: parseFloat(faker.commerce.price()),
quantity: faker.number.int({ min: 1, max: 5 })
}))
);
打開apps\iron-ecommerce-next\app\products\products.client.tsx
"use client";
import { gql, useQuery } from "@apollo/client";
import { Flex } from "@radix-ui/themes";
import { useCartActions } from "../../store/actions/cart.actions";
import { Product } from "../../store/schemas/product.schema";
import ProductCard from "libs/iron-components/src/lib/ProductCard";
import { Get_ProductsQuery } from "../../__generated__/generated-hooks";
interface ProductsProps {
products: Product[];
}
const ProductsClient = ({ products }: ProductsProps) => {
const { addToCart } = useCartActions();
const {data} = useQuery<Get_ProductsQuery>(gql`
query GET_PRODUCTS {
getProducts @client {
id
name
description
price
imageUrl
}
}
`);
console.log(data);
return (
<Flex align="center" justify="center">
<section className="w:60% p:1rem flex flex:wrap flex-direction:row gap:1rem jc:center">
{products.map((product, i) => (
<ProductCard
key={product.id}
title={product.name}
price={`$${product.price.toFixed(2)}`}
description={product.description}
width="30%"
imageUrl={product.imageUrl}
onAddToCart={() =>
addToCart({
productId: product.id,
productName: product.name,
quantity: 1,
price: product.price
})
}
/>
))}
</section>
</Flex>
);
};
export default ProductsClient;
執行並觀看
pnpm exec nx run iron-ecommerce-next:serve
在本文中,我們展示了如何使用模擬數據來模擬真實的API回應