使用React和TypeScript,尝试使用Apollo Client进行GraphQL查询

Apollo Client是用于React的状态管理库。它可以处理本地和远程数据,并使用GraphQL进行操作。本篇文章介绍的是Apollo Client官方提供的“开始使用Apollo Client”中的示例。然而,我们采用了TypeScript,并对应用程序进行了简单的模块化处理。

准备创建Apollo Client应用程序。

我决定使用Create React App来创建React应用程序的模板。如果添加–template typescript选项,则可以轻松添加TypeScript环境,非常方便(参见”使用Create React App创建包含TypeScript的模板应用程序”)。

让我们安装Apollo Client吧。由于GraphQL也有依赖关系,请一并安装(即使您不使用查询也是必需的)。

npm install @apollo/client graphql

初始化ApolloClient。

首先,我们创建ApolloClient的实例。构造函数使用了一个选项对象作为参数,并设置了两个配置项。其中,uri是GraphQL服务器的URL字符串。cache是Apollo Client用来保存已加载的查询结果的必需项,通常情况下会指定为InMemoryCache实例。

uri: string – Apollo Clientが通信するGraphQLのエンドポイントURI。

cache: ApolloCache – クエリの結果をローカルに保存するためにApollo Clientが用いるべきキャッシュ(必須)。 @apollo/clientパッケージの提供するInMemoryCacheが推奨。

暫時不考慮將資料插入React頁面,現在嘗試著提交查詢(代碼001)。對於ApolloClient實例,請調用query()方法。請將查詢字符串用gql模板字面量包裝,作為參數傳遞。

使用ApolloClient发送查询的代码001.

import { useEffect } from 'react';
import {
	ApolloClient,
	InMemoryCache,
	gql,
} from '@apollo/client';

const client = new ApolloClient({
	uri: 'https://48p1r2roz4.sse.codesandbox.io',
	cache: new InMemoryCache(),
});
function App() {
	useEffect(() => {
		client
			.query({
				query: gql`
					query GetRates {
						rates(currency: "USD") {
							currency
						}
					}
				`,
			})
			.then((result) => console.log(result));
	}, []);
	return (
		<div>
			<h1>Apollo Client</h1>
		</div>
	);
}
export default App;

运行代码后,您应该在控制台上看到查询结果对象(见图001)。请确认以下示例001在CodeSandbox上已公开,并查看其运行情况。

输出到控制台的查询结果

2203002-001.png

標本001■使用React + TypeScript: 使用Apollo Client 01進行GraphQL查詢

 

将ApolloProvider连接到React上下文中。

使用ApolloProvider组件可以将Apollo Client连接到React的上下文中。这个机制与React的Context.Provider相同。从包装的组件树中的任何组件都可以访问Apollo Client的数据。请将使用GraphQL数据的根组件包含在ApolloProvider中。传递给属性client的是ApolloClient实例。

// import { useEffect } from 'react';
// import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
import {

	ApolloProvider,

} from '@apollo/client';

function App() {
	/* useEffect(() => {

	}, []); */
	return (
		<ApolloProvider client={client}>
			<div>

			</div>
		</ApolloProvider>
	);
}

使用 useQuery 钩子来加载数据。

一旦将这段文本翻译成中文,然后再进行改写:

当通过ApolloProvider将React与上下文连接起来后,可以通过查询来加载数据到页面中。我们要使用的钩子是useQuery。它可以使React与GraphQL数据进行共享。我们将在根模块(src/App.tsx)中使用变量(ExchangeRates)来定义查询。除了货币(currency)之外,我们还添加了汇率(rate)作为要获取的属性。然后将查询添加到将要定义的子组件(ExchangeRates)的属性(exchangeRates)中。

改写后的文本如下:
当通过ApolloProvider与React的上下文连接时,可以使用useQuery这个钩子来通过查询将数据加载到页面中。我们将GraphQL的数据与React共享。在根模块(src/App.tsx)中,通过变量(ExchangeRates)来定义查询。除了货币(currency)之外,我们还添加了汇率(rate)作为要获取的属性。然后将查询添加到即将定义的子组件(ExchangeRates)的属性(exchangeRates)中。

import { ExchangeRates } from './ExchangeRates';

const EXCHANGE_RATES = gql`
	query GetExchangeRates {
		rates(currency: "USD") {
			currency
			rate
		}
	}
`;
function App() {
	return (
		<ApolloProvider client={client}>
			<div>

				<ExchangeRates exchangeRates={EXCHANGE_RATES} />
			</div>
		</ApolloProvider>
	);
}

每次组件渲染时,使用Query Hook传递的查询(DocumentNode类型)都会被执行,并返回一个新结果对象。现在,显示汇率的子模块(src/ExchangeRates.tsx)正在提取三个属性(代码002)。

loading: boolean – ロード中かどうかのブール値。trueのときは、まだクエリの結果が返されていない。

error: ApolloError – クエリにエラーが起こったことを示すオブジェクト。

data: TData – GraphQLクエリが正しく実行されたときに得られる結果のデータ。

运行代码后,将会显示一段时间的 “Loading…” 文本,然后显示汇率列表。这意味着根据查询状态,组件会被动态地重新渲染。同时,我还整理了重写的根模块 (src/App.tsx) 的代码。您可以在CodeSandbox上查看下面的样例002来确认功能。

使用useQuery钩子加载的数据在页面上显示。

import { VFC } from 'react';
import {
	DocumentNode,
	useQuery,
} from '@apollo/client';

type Props = {
	exchangeRates: DocumentNode;
};
export const ExchangeRates: VFC<Props> = ({ exchangeRates }) => {
	const { loading, error, data } = useQuery(exchangeRates);
	if (loading) return <p>Loading...</p>;
	if (error) return <p>Error :(</p>;
	return data.rates.map(
		({ currency, rate }: { currency: string; rate: string }) => (
			<div key={currency}>
				<p>
					{currency}: {rate}
				</p>
			</div>
		)
	);
};
import {
	ApolloClient,
	ApolloProvider,
	InMemoryCache,
	gql
} from '@apollo/client';
import { ExchangeRates } from './ExchangeRates';

const client = new ApolloClient({
	uri: 'https://48p1r2roz4.sse.codesandbox.io',
	cache: new InMemoryCache(),
});
const EXCHANGE_RATES = gql`
	query GetExchangeRates {
		rates(currency: "USD") {
			currency
			rate
		}
	}
`;
function App() {
	return (
		<ApolloProvider client={client}>
			<div>
				<h1>Apollo Client</h1>
				<ExchangeRates exchangeRates={EXCHANGE_RATES} />
			</div>
		</ApolloProvider>
	);
}
export default App;

React + TypeScript: 使用 Apollo Client 02 进行 GraphQL 查询的示例002。

 

另外,在CodeSandbox上,如果将graphql的版本升级到16以上,似乎会出现TypeError的问题。
bannerAds