Apollo Client (React) 触ってみた。 Mutations編

前回の続き

https://shikatech.hatenablog.com/entry/2021/07/03/222958

Mutations

GraphQLのMutationを実行するHooks

https://www.apollographql.com/docs/react/data/mutations/#prerequisites

  const [addTodo, { data }] = useMutation(ADD_TODO);

useQueryと違い自動実行ではない。 タプルで発火用の関数(addTodo)を返し、任意のタイミングで実行させる。

useMutation、生成された発火関数、どちらでもオプションを指定でき、 別のオプションを指定した場合はuseMutationをオーバーライドして使う。

cacheも自動更新される。

使ってみた。

  const [updateTask] = useUpdateTaskMutation()


<button onClick={()=>updateTask({
                  variables: {
                    id: task?.id as string,
                    completed: task?.completed === 1 ? 0 : 1
                  }
                })}>
                  ✔︎
</button>

f:id:shikatech:20210704115812p:plain

cacheの値もDBも更新された。

上記は単一のレコードを変更した場合で、 複数のレコードを同時に更新する場合は自動でcache更新は行われない。

cacheも同時に変更する為にはupdate()関数が必要。

以下ドキュメントから抜粋 https://www.apollographql.com/docs/react/data/mutations/#making-all-other-cache-updates

const GET_TODOS = gql`
  query GetTodos {
    todos {
      id
    }
  }
`;

function AddTodo() {
  let input;
  const [addTodo] = useMutation(ADD_TODO, {
    update(cache, { data: { addTodo } }) {
      cache.modify({
        fields: {
          todos(existingTodos = []) {
            const newTodoRef = cache.writeFragment({
              data: addTodo,
              fragment: gql`
                fragment NewTodo on Todo {
                  id
                  type
                }
              `
            });
            return [...existingTodos, newTodoRef];
          }
        }
      });
    }
  });

  return (
    <div>
      <form
        onSubmit={e => {
          e.preventDefault();
          addTodo({ variables: { type: input.value } });
          input.value = "";
        }}
      >
        <input
          ref={node => {
            input = node;
          }}
        />
        <button type="submit">Add Todo</button>
      </form>
    </div>
  );
}

ほかにもAPIが提供されているが、useQueryと重複するモノも多かった為、 Mutations編はここまで。

Subscriptionはバックエンドが出来ればやっていきたいと思う。