Closed5
React x ApolloClient で Fragment Colocation
React x Apollo Client で Fragment Colocation の使い方を調べたときのメモ
ライブラリ
"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 版を使っている(特に理由はない)
codegen.yml
overwrite: true
schema: './schema.graphql'
documents:
- 'src/**/*.ts'
generates:
src/generated/graphql.ts:
plugins:
- 'typescript'
- 'typescript-operations'
./graphql.schema.json:
plugins:
- 'introspection'
schema.graphql は下記の内容を拝借
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
に型情報を持たせることができる。
詰まった点
msw x Apollo Client を使っている場合それぞれの response に __typename
を含める必要がある。
msw のレスポンスで __typename
を指定していないと fragment 部分のレスポンスが取得できなくなる
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にクローズされました