Closed5

React x ApolloClient で Fragment Colocation

FUJITA kazuya 🐠FUJITA kazuya 🐠

React x Apollo Client で Fragment Colocation の使い方を調べたときのメモ

https://github.com/ayuzaka/react-apollo-sample

ライブラリ

  "dependencies": {
    "@apollo/client": "^3.6.0-beta.13",
    "graphql": "^16.3.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  "devDependencies": {
    "@graphql-codegen/cli": "2.6.2",
    "@graphql-codegen/introspection": "2.1.1",
    "@graphql-codegen/typescript": "2.4.8",
    "@graphql-codegen/typescript-operations": "2.3.5",
    "msw": "^0.39.2",
    "typescript": "^4.6.3",
    "vite": "^2.9.2",
    ... 一部省略)
  },

  • msw でモックを作成しローカルで確認できるようにしている
  • apollo/client 3.5(2022/04/16 現在の最新版)が React18 に対応していないため beta 版を使っている(特に理由はない)
FUJITA kazuya 🐠FUJITA kazuya 🐠

PokemonList.tsx

import { useQuery, gql } from '@apollo/client';
import type { FC } from 'react';
import { PokemonTypes, POKEMON_TYPES_FRAGMENT } from '../PokemonType/PokemonType';
import type { PokemonListQuery, PokemonListQueryVariables } from '../../generated/graphql';

const POKEMON_LIST_QUERY = gql`
  ${POKEMON_TYPES_FRAGMENT}
  query PokemonList($first: Int!) {
    pokemons(first: $first) {
      id
      name
      ...PokemonTypes
    }
  }
`;

export const PokemonList: FC = () => {
  const { loading, error, data } = useQuery<PokemonListQuery, PokemonListQueryVariables>(POKEMON_LIST_QUERY, {
    variables: { first: 3 },
  });

  if (loading) {
    return <p>Loading...</p>;
  }

  if (error) {
    return <p>Error :( </p>;
  }

  if (!data?.pokemons) {
    return <p>data is empty</p>;
  }

  return (
    <div>
      {data.pokemons.map(
        (pokemon) =>
          pokemon !== null && (
            <div key={pokemon.id}>
              <p>{pokemon.name}</p>
              <PokemonTypes pokemon={pokemon} />
            </div>
          )
      )}
    </div>
  );
};

useQuery にジェネリクスを指定することで data に型情報を持たせることができる。

FUJITA kazuya 🐠FUJITA kazuya 🐠

PokemonType.tsx

import type { FC } from 'react';
import { gql } from '@apollo/client';
import type { PokemonTypesFragment } from '../../generated/graphql';

export const POKEMON_TYPES_FRAGMENT = gql`
  fragment PokemonTypes on Pokemon {
    types
  }
`;

type Props = {
  pokemon: PokemonTypesFragment;
};

export const PokemonTypes: FC<Props> = ({ pokemon }) => {
  return <div>{pokemon.types?.toString()}</div>;
};
このスクラップは2022/04/18にクローズされました