React TypeScript中如何调用GraphQL接口并渲染返回的列表数据
React + TypeScript 调用GraphQL接口渲染Products列表
根据项目规模可以选择两种实现方案,两种方案的请求逻辑和你在Postman中的配置完全一致。
方案1:原生fetch实现(无额外依赖,适合快速验证/小型项目)
不需要安装第三方依赖,直接用浏览器原生能力发请求即可。
- 先定义TS类型,对齐接口结构
// 单条列表项类型 type ProductItem = { id: string | number; name: string; sortOrder: number; }; // GraphQL返回数据结构 type QueryResponse = { data?: { listByName: ProductItem[]; }; errors?: { message: string }[]; };
- 编写组件,在组件挂载时发起请求,管理加载、错误、数据状态
注意:将代码中的YOUR_GRAPHQL_SERVICE_URL替换为你实际的GraphQL服务地址,鉴权等请求头和Postman配置保持一致
import { useEffect, useState } from 'react'; const ProductList = () => { const [productList, setProductList] = useState<ProductItem[]>([]); const [loading, setLoading] = useState(true); const [errorMsg, setErrorMsg] = useState(''); useEffect(() => { const fetchList = async () => { try { setLoading(true); const resp = await fetch('YOUR_GRAPHQL_SERVICE_URL', { method: 'POST', headers: { 'Content-Type': 'application/json', // 接口需要鉴权时添加对应请求头即可 // 'Authorization': `Bearer ${localStorage.getItem('access_token')}` }, body: JSON.stringify({ query: ` query listByName($name: String!) { listByName(name: $name) { id name sortOrder } } `, variables: { name: 'Products' } }) }); if (!resp.ok) throw new Error(`请求异常,状态码:${resp.status}`); const result = await resp.json() as QueryResponse; if (result.errors?.length) throw new Error(result.errors.map(e => e.message).join(';')); setProductList(result.data?.listByName || []); } catch (err) { setErrorMsg(err instanceof Error ? err.message : '加载失败'); } finally { setLoading(false); } }; fetchList(); }, []); if (loading) return <div>加载中...</div>; if (errorMsg) return <div>加载失败:{errorMsg}</div>; return ( <div> <h3>Products</h3> <ul> {/* 按sortOrder升序排序后渲染 */} {[...productList].sort((a,b) => a.sortOrder - b.sortOrder).map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }; export default ProductList;
方案2:Apollo Client实现(中大型项目推荐)
如果项目后续有大量GraphQL请求,推荐用Apollo Client,自带请求缓存、状态同步、自动重试等能力,减少重复样板代码。
- 安装依赖
npm install @apollo/client graphql
- 在项目入口(如
main.tsx)初始化客户端,全局注入Provider
import React from 'react'; import ReactDOM from 'react-dom/client'; import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'; import App from './App'; // 初始化GraphQL客户端 const gqlClient = new ApolloClient({ uri: 'YOUR_GRAPHQL_SERVICE_URL', // 替换为你的GraphQL地址 cache: new InMemoryCache(), // 鉴权头和其他公共头可以在这里统一配置 // headers: { // Authorization: `Bearer ${localStorage.getItem('access_token')}` // } }); ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <ApolloProvider client={gqlClient}> <App /> </ApolloProvider> </React.StrictMode> );
- 在组件中直接用封装好的Hook发请求
import { gql, useQuery } from '@apollo/client'; // 定义查询语句 const GET_PRODUCT_LIST = gql` query listByName($name: String!) { listByName(name: $name) { id name sortOrder } } `; // 定义TS类型 type ProductItem = { id: string | number; name: string; sortOrder: number; }; type QueryData = { listByName: ProductItem[] }; type QueryVars = { name: string }; const ProductList = () => { const { data, loading, error } = useQuery<QueryData, QueryVars>(GET_PRODUCT_LIST, { variables: { name: 'Products' } }); if (loading) return <div>加载中...</div>; if (error) return <div>加载失败:{error.message}</div>; const productList = data?.listByName || []; return ( <div> <h3>Products</h3> <ul> {[...productList].sort((a,b) => a.sortOrder - b.sortOrder).map(item => ( <li key={item.id}>{item.name}</li> ))} </ul> </div> ); }; export default ProductList;
常见踩坑说明
- 所有请求头配置和你Postman里的配置保持一致即可,避免出现权限、参数不匹配类错误
- 本地调试如果出现跨域拦截,需要在GraphQL服务端配置CORS规则,允许你的前端域名访问
- GraphQL接口即使返回200状态码,也可能在返回体的
errors字段携带业务错误,需要单独判断处理
内容的提问来源于stack exchange,提问作者lorijames95
相关产品推荐
相关产品推荐

