React + Apollo Client -Mutation CRUD編-
このセクションでは新しくTodoを作成したり編集するための機能をコードで書いていきます。
AddTodo.jsの作成
src/graphql/mutationsにaddTodo.jsを作成します。
// src/graphql/mutatios/addTodo.js
import { gql } from "@apollo/client";
export const CREATE_TODO = gql `
mutation createTodoMutation($content: String!){
createTodo(content: $content){
id
content
}
}`
続いてはTodoを作成するためのページをつくります。src/pages下にAddTodo.jsを新しくつくり以下のようにコードをかいていきます、
// src/pages/AddTodo.js
import React, { useEffect, useState } from 'react'
import { ADD_TODO } from '../graphql/mutations/addTodo'
import { useHistory } from 'react-router';
import { useMutation, useQuery } from '@apollo/client';
import { ME_QUERY } from '../graphql/queries/me';
function AddTodo() {
const history = useHistory();
const [ content, setContent ] = useState("")
const { loading, data } = useQuery(ME_QUERY)
const [addTodo] = useMutation(ADD_TODO, {
variables: {
content
},
onCompleted: () => {
history.push('/')
}
})
const onSubmit = (e) => {
e.preventDefault();
addTodo();
}
useEffect(() => {
if(!loading && !data.me){
history.push('/login')
}
},[loading, data, history])
return (
<form onSubmit={onSubmit}>
<input type="text" value={content} onChange={(e) => setContent(e.target.value)} />
<button type="submit">ADD TODO</button>
</form>
)
}
export default AddTodo
まずは前回ユーザー認証のときに実装したようにuseMutationとaddTodo.jsに定義したスキーマを使用し、addTodo関数を実装します。送信が完了すると確認のためトップページへ戻ります。もしくはconsole.log(addTodo)などで確認しても構いません。
さらにログインしていないユーザーをログイン画面へとかえすためにuseEffectを使って上のように実装します。前回のセクションで最後に実装したユーザー確認に似ていると思います。
Todoの編集と削除
最後にCRUD機能のUPDATEとDELETEを実装して終わります。やり方は今までと変わりません。まずMutationの定義からおこないます。graphql/mutations下に以下のファイルを作成して定義していきます。
// src/graphql/queries/me.js
import { gql } from "@apollo/client";
export const ME_QUERY = gql `
query Me {
me {
id
username
email
}
}
}`
Todoを表示しているトップページにそれぞれの機能を加えます。
// src/pages/TodoListing.js
import React, { useState } from 'react'
import { useMutation, useQuery } from '@apollo/client';
import { GET_TODOS } from '../graphql/queries/listingTodo';
import { DELETE_TODO } from '../graphql/mutations/deleteTodo';
import { UPDATE_TODO } from '../graphql/mutations/updateTodo';
import { ME_QUERY } from '../graphql/queries/me';
function TodoListing() {
const { loading, error, data } = useQuery(GET_TODOS)
const [ deleteTodo ] = useMutation(DELETE_TODO)
const [ updateTodo ] = useMutation(UPDATE_TODO)
const { loading: meLoading, data: meData } = useQuery(ME_QUERY)
const [ todo, setTodo ] = useState("")
if( loading | meLoading ){
return (
<p>Loading....</p>
)
}
if( error ){
return (
<p>Something went wrong!!</p>
)
}
return (
<div>
{data.listing.map(({id, content})=> {
return (
<>
<div key={id}>
<form>
<p>{id}</p>
<p>{content}</p>
{ meData.me && (
<>
<div>
<label>編集</label>
<input type="text" onChange={(e) => setTodo(e.target.value) } />
<button onClick={() => {
updateTodo({
variables: {
id: parseInt(id),
content: todo
}
})
setTodo("")}
}
type="submit">アップデート</button>
</div>
<p>
<button onClick={() => {
deleteTodo({
variables: { id: parseInt(id) }
})
}}>削除</button></p>
</>
)}
</form>
</div>
</>
)
})}
</div>
)
}
export default TodoListing
まずここでもログインしているユーザーのみが変更を行えるようにME_QUERYを使っています。
const { loading: meLoading, data: meData } = useQuery(ME_QUERY)
変数dataはすでに使っているのでここではdataをmeDataに変えておきます。下記のコードはmeDataからユーザーデータを得たもののみが表示されます。
// src/pages/TodoListing.js
{ meData.me && (
<>
<div>
<label>編集</label>
<input type="text" onChange={(e) => setTodo(e.target.value) } />
<button onClick={() => {
updateTodo({
variables: {
id: parseInt(id),
content: todo
}
})
setTodo("")}
}
type="submit">アップデート</button>
</div>
<p>
<button onClick={() => {
deleteTodo({
variables: { id: parseInt(id) }
})
}}>削除</button></p>
</>
)}
updateTodoではidと変更する内容であるcontentを渡しています。deleteTodoでは削除したいTodoのidを渡しています。
上のようにTodoと編集と削除ボタンができたおり無事にデータの更新を行えれば成功です。またログインしたときに得たcookieを削除してみてください。
削除後ページをリフレッシュすると上のようにデータの変更ができなくなっています。
これで基本的なCRUD機能を実装できたので次はcacheについて学習していきます。ここまでのコードはしたに置いておくので確認してみてください。