🪙

ReactNativeでGraphQLを使ってみた

2024/03/20に公開

読んでほしい人

  • ReactNativeに興味ある人
  • GraphQLに興味がある人

補足情報

こちらのNest.jsで作成したGraphQL APIを使うので、git cloneして、使ってください。
https://github.com/sakurakotubaki/nest-graphql-app

以下のコマンドを実行して使えると思います。
npmのパッケージをインストールする。

npm i

ローカルサーバーを起動する。

npm run start

こちらのエンドポイントにアクセスするとブラウザで、GraphQLを操作できます。
http://localhost:3000/graphql

以下のクエリを実行すると、mockのデータを取得できます。

# Write your query or mutation here
{
  users {
    id
    name
    email
  }
}

今回はこちらのAPIを使用して、ReactNativeからデータを取得して表示してみましょう。

記事の内容

ReactNativeにGraphQLのライブラリーを追加してコードを記述していきましょう。
https://www.apollographql.com/docs/react/integrations/react-native/

こちらが完成品です
https://github.com/sakurakotubaki/react-native-graphql

GraphQLのスキーマに合わせて、インターフェースを定義します。この書き方でないとうまくいかなかったので、こんな風に書いてください。

interface User {
  id: string;
  name: string;
  email: string;
}

interface UsersData {
  users: User[];
}

Nest.jsのAPIにアクセスするURLを指定してコードには、ブラウザで実行したクエリを記述します。公式のコメントのInitialize Apollo Clientを翻訳してみると、ApolloClientを初期化しているそうです。

const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql',
  cache: new InMemoryCache()
});

const USERS_QUERY = gql`
  query GetUsers {
    users {
      id
      name
      email
    }
  }
`;

GraphQLを使うには、ApolloProviderでコンポーネントをラップする必要があるようです。

export default function App() {
  return (
    <ApolloProvider client={client}>
      <SafeAreaView style={styles.safeArea}>
        <View style={styles.container}>
          <Users />
        </View>
      </SafeAreaView>
    </ApolloProvider>
  );
}

こちらが全体のコードです。レイアウトを綺麗にしたかったので、整えておきました。

import { FlatList, Text, View, StyleSheet, StatusBar, SafeAreaView } from 'react-native';
import { ApolloClient, InMemoryCache, ApolloProvider, useQuery, gql } from '@apollo/client';

interface User {
  id: string;
  name: string;
  email: string;
}

interface UsersData {
  users: User[];
}

const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql',
  cache: new InMemoryCache()
});

const USERS_QUERY = gql`
  query GetUsers {
    users {
      id
      name
      email
    }
  }
`;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
    backgroundColor: '#f5f5f5',
  },
  item: {
    backgroundColor: '#fff',
    padding: 20,
    marginVertical: 8,
    marginHorizontal: 16,
  },
  title: {
    fontSize: 32,
  },
  safeArea: {
    flex: 1,
    marginTop: StatusBar.currentHeight || 0,
  },
});

function Users() {
  const { loading, error, data } = useQuery<UsersData>(USERS_QUERY);

  if (loading) return <Text>Loading...</Text>;
  if (error) return <Text>Error :(</Text>;

  return data && data.users ? (
    <FlatList
      data={data.users}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text style={styles.title}>{item.name}</Text>
          <Text>{item.email}</Text>
        </View>
      )}
    />
  ) : null;
}

export default function App() {
  return (
    <ApolloProvider client={client}>
      <SafeAreaView style={styles.safeArea}>
        <View style={styles.container}>
          <Users />
        </View>
      </SafeAreaView>
    </ApolloProvider>
  );
}

こんな感じで表示できます。

最後に

今回は、GraphQLをReactNativeで使ってみました。Flutterで以前GraphQLを使ってみたのですが、ライブラリーが使いづらくて、ReactNativeはどうかと試してみたところ、Reactと同じような感覚で使えたので、使いやすいなと思いました。
Flutterにもferryだとか専用のライブラリあるのですが、情報が少なくって簡単なもの作るだけで難しかったです💦

Discussion