🐥

React + GraphQL + Apolloを触ってみる ~ 2. ToDoリストの読み込みまで ~

2023/03/09に公開

前回からの続き

ToDoリストをサーバ側でモック用意してフロント側で表示するところまで

目次

  1. GraphQLの環境構築まで
  2. ToDoリストの読み込みまで
  3. Firebaseの準備とGraphQLとの連携部分まで
  4. ToDoの追加・編集・削除まで

サーバ側

スキーマ、resolverの分割とToDo用の作成

前回はindex.mjsにスキーマやresolverを直接書いていたので、今後のためにファイル分けつつToDo用にスキーマ、resolverを作成

src/schema.js
const typeDefs = `#graphql
  type Todo {
    id: ID!,
    text: String,
    isCompleted: Boolean,
  }
  type Query {
    getTodos: [Todo],
  }
`

export default typeDefs
src/resolvers.js
import { Query } from './resolvers/query.js'

const resolvers = { Query }
export default resolvers
src/resolvers/query.js
export const Query = {
  getTodos (parent, args, context) {
    return context.todos
  },
}

この段階では一旦resolverの中身はcontextから取得したものをそのまま帰すようにしておく。

あとは作成したものをindex.mjsから読み込む

src/index.jsm
import bodyParser from 'body-parser'
+ import typeDefs from './schema.js'
+ import resolvers from './resolvers.js'

- const typeDefs = ```#graphql
-   type Query {
-     hello: String
-   }
-     ```
- 
- const resolvers = {
-   Query: {
-     hello: () => 'Hello GraphQL'
-   }
- }

モックでテスト用データを用意してindex.mjsから読み込む

src/index.mjs
app.use(
  cors(),
  bodyParser.json(),
-   expressMiddleware(server)
+   expressMiddleware(server, {
+     context: async ({ req }) => ({
+       todos: [
+         {
+           id: '1',
+           text: 'hoge',
+           isCompleted: false,
+         },
+         {
+           id: '2',
+           text: 'fuga',
+           isCompleted: false,
+         },
+         {
+           id: '3',
+           text: 'piyo',
+           isCompleted: true,
+         },
+       ]
+     })
+   })
)

プレイグラウンドで確認

フロントエンド

クエリの分割とTodo用クエリの作成

フロント側もクエリを別ファイルに分割しておく

src/types/todo.ts
export interface Todo {
  id: String
  text: String
  isCompleted: Boolean
}
src/queries/todos.query.ts
import { gql } from '@apollo/client'
import { Todo } from '@/types/todo'

export const TODOS_QUERY = gql`
  query getTodos {
    getTodos {
      id
      text
      isCompleted
    }
  }
`

export interface TodosData {
  getTodos: Todo[]
}

あとはインデックスページから読み込んで終わり

src/pages/index.tsx
import { useQuery } from '@apollo/client'
import { NextPage } from 'next'
import { TODOS_QUERY } from '@/queries/todos'

interface IndexPageProps {}

const IndexPage: NextPage<IndexPageProps> = (props: IndexPageProps) => {
  const { loading, error, data } = useQuery(TODOS_QUERY)
  if (loading) {
    return <div>loading..</div>
  }

  if (error) {
    return <div>error: {error.message}</div>
  }

  if (!data.getTodos) {
    return null
  }

  return (
    <ul>
      {data.getTodos.map(({ id, text, isCompleted }) => (
        <li key={id}>
          <div>id: {id}</div>
          <div>text: {text}</div>
          <div>isCompleted: {isCompleted ? 'true' : 'false'}</div>
        </li>
      ))}
    </ul>
  )
}
export default IndexPage

次はToDoリストの追加や編集をしたいので、FirebaseのCloudFirestoreを使う準備とGraphQLとの連携部分を作る

Discussion