はじめに
GrahQLをサポートするApolloClientと、React CustomHookを使って、サーバ上のデータを取得する方法を紹介します。
サンプルイメージ
今回はバックエンドGrahQLサーバとして、SpaceXが提供しているGrahQL APIを利用します。
前提
create-react-app等で、既にReactプロジェクトが作成されていること。
手順
- ライブラリインストール
- AppolloClientの設定
- useQueryでデータ取得
ライブラリインストール
下記を実行し、ApolloClientをインストールする。
npm install @apollo/client graphql
AppolloClientの設定
上位のコンポーネント(index.jsとか)で必要なオブジェクトをimportする。
import {
ApolloClient,
InMemoryCache,
ApolloProvider
} from "@apollo/client";
ApolloClientをSpaceXのGraphQLサーバと接続するように設定し、インスタンス化する。
(ここで指定するcache
は、ApolloClientを通じてやり取りしたデータのキャッシュを保持するオブジェクトのこと。cache
内のデータはApolloProviderにラップされているコンポーネントならどこからでも参照できます。)
const client = new ApolloClient({
uri: 'https://api.spacex.land/graphql/',
cache: new InMemoryCache()
});
その後、下記のようにGraphQLサーバと接続するコンポーネントをApolloProvider
でラップしてあげる。(ApolloProvider配下にいる場合のみ、引数として受け渡されたclient
を使ってリクエストを投げることができます。)
ReactDOM.render(
<React.StrictMode>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</React.StrictMode>,
document.getElementById('root')
);
ここまでのindex.js
全体
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {
ApolloClient,
InMemoryCache,
ApolloProvider,
} from "@apollo/client";
const client = new ApolloClient({
uri: 'https://api.spacex.land/graphql/',
cache: new InMemoryCache()
})
ReactDOM.render(
<React.StrictMode>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</React.StrictMode>,
document.getElementById('root')
);
useQueryでデータ取得
ここから、データ取得のロジックを作成していきます。
下記を実行し、GrahQLサーバへのリクエストクエリ発行に必要なオブジェクトをimportします。
import {
useQuery,
gql
} from "@apollo/client";
クエリ作成
gql
を利用して、クエリを作成します。
下記クエリはSpaceX GrahQL APIから、指定した名前の船情報(船名・画像・id)を取得するクエリです。
const GET_SHIPS = gql`
query GetShips() {
ships(find: {name: 'American Champion'}) {
name
image
id
}
}
`;
クエリのリクエスト
作成したクエリをuseQuery
を使って、リクエストします。
useQuery
は{ loading, error, data }
を返却します。
ロード中であればloading
、
エラーが発生すればerror
、
正常にデータが取得出来たらdata
を返却します。
上記以外にもuseQuery
はいろいろ便利なもの返却するので、下記参照してみてください。
https://www.apollographql.com/docs/react/data/queries/#usequery-api
const shipName = '';
const { loading, error, data } = useQuery(GET_SHIPS ,{
variables: {name: shipName},
});
if (loading) return 'loading';
if (error) return 'error';
return {
shipData:data.ships
}
上記ロジックをカスタムフックにまとめたコードが下記になります。
import './App.css';
import {
useQuery,
gql
} from "@apollo/client";
import React from 'react';
function useExchangeRates() {
const GET_SHIPS = gql`
query GetShips() {
ships(find: {name: "American Champion"}) {
name
image
id
}
}
`;
const shipName = 'American Champion';
const { loading, error, data } = useQuery(GET_SHIPS);
if (loading) return 'loading';
if (error) return 'error';
return {
shipData:data.ships
}
}
function ShowshipData(props){
if(!props.shipData){
return(<p>no data</p>);
}else if (props.shipData === 'loading'){
return(<p>loading</p>);
}else if(props.shipData === 'error'){
return(<p>loading</p>);
}
return props.shipData.map(({ name, image }) => (
<div>
<p>{name}</p>
<img src={image} alt=''/>
</div>
));
}
function App() {
console.log("App rerendered");
const {shipData} = useExchangeRates();
return (
<div className="App">
<div>
<ShowshipData shipData={shipData}/>
</div>
</div>
);
}
export default App;
以上が、GrahQLサーバのデータを取得する方法になります。
おまけ
リクエストの引数(variables)を変えて、再度データ取得を行う
上記コード例の場合、クエリのvariables
が固定値(American Champion)です。
任意のvariablesを指定かつ、一度実行したクエリを手軽に再実行する方法を紹介します。
クエリ作成
クエリを下記の通り修正します。
GetShips
クエリが、引数としてname
を受け取る宣言をしてます。
function useExchangeRates() {
const GET_SHIPS = gql`
query GetShips($name: String!) {
ships(find: {name: $name}) {
name
image
id
}
}
`;
クエリのリクエスト
useQuery
の第二引数で指定しているvariables
がクエリの引数になります。(今回で言うと船名)
const shipName = 'other ship';
const { loading, error, data, refetch } = useQuery(GET_SHIPS ,{
variables: {name: shipName},
});
上記実行すると、指定した船名のデータを取得することができます。
補足:
上記のようにuseQuery
の返り値として、refetch
を取得しておけば、次回データ取得の際に下記のように利用することができます。
refetch({
variables: {name: shipName}
})
参考