JavaRush /Курсы /Модуль 3: React /Отправка mutation для изменения данных — примеры

Отправка mutation для изменения данных — примеры

Модуль 3: React
12 уровень , 4 лекция
Открыта

Что такое мутация?

Если запросы (queries) в GraphQL можно сравнить с чтением данных из базы, то мутации (mutations) — это операции записи, добавления, обновления или удаления данных. Они вносят изменения на сервере. В отличие от запросов, мутации всегда выполняются последовательно (даже если вы отправляете несколько мутаций одновременно).

Мутации пишутся почти так же, как и запросы. Основное отличие — ключевое слово mutation. Вот пример базового синтаксиса:

mutation {
  addUser(name: "Alice", email: "alice@example.com") {
    id
    name
    email
  }
}

В этом примере мы добавляем пользователя с именем "Alice". В ответ сервер возвращает id, name и email нового пользователя.

Зачем это нужно? Мутации позволяют клиенту изменять состояние данных на сервере, будь то добавление новой записи в базу данных, обновление профиля пользователя или удаление данных.

Реализация мутаций с использованием Apollo Client

Теперь, когда у нас есть представление о том, что такое мутации, давайте окунёмся в код. Для работы с мутациями в Apollo Client используется хук useMutation.

Если вы ещё не настроили Apollo Client, сделайте это, следуя инструкциям из предыдущих лекций. Убедитесь, что ваш клиент настроен и подключён к GraphQL серверу.

Для демонстрации мы будем работать с мутацией, которая добавляет пользователя. Вот пример исходного GraphQL:

mutation AddUser($name: String!, $email: String!) {
  addUser(name: $name, email: $email) {
    id
    name
    email
  }
}

Использование useMutation в React-компоненте

Создаем мутацию в React:

import React, { useState } from 'react';
import { gql, useMutation } from '@apollo/client';

// Определяем GraphQL-мутaцию
const ADD_USER = gql`
  mutation AddUser($name: String!, $email: String!) {
    addUser(name: $name, email: $email) {
      id
      name
      email
    }
  }
`;

interface User {
  id: string;
  name: string;
  email: string;
}

const AddUserForm: React.FC = () => {
  const [name, setName] = useState<string>('');
  const [email, setEmail] = useState<string>('');

  // Используем хук useMutation
  const [addUser, { data, loading, error }] = useMutation<{ addUser: User }>(ADD_USER);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      const result = await addUser({ variables: { name, email } });
      console.log('New user added:', result.data?.addUser);
    } catch (err) {
      console.error('Error adding user:', err);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Name: </label>
        <input
          type="text"
          value={name}
          onChange={(e) => setName(e.target.value)}
          required
        />
      </div>
      <div>
        <label>Email: </label>
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required
        />
      </div>
      <button type="submit" disabled={loading}>
        {loading ? 'Adding...' : 'Add User'}
      </button>
      {error && <p style={{ color: 'red' }}>Error: {error.message}</p>}
      {data && (
        <p style={{ color: 'green' }}>
          User added: {data.addUser.name} ({data.addUser.email})
        </p>
        )}
    </form>
  );
};

export default AddUserForm;

Что здесь происходит?

  1. Мы определяем мутaцию ADD_USER с переменными $name и $email.
  2. Используем хук useMutation, чтобы отправить запрос на сервер.
  3. Обрабатываем ввод пользователя через useState.
  4. При отправке формы вызываем переданную функцией addUser, передавая значения переменных.

Обработка результатов мутаций

После выполнения мутации вы можете обновить интерфейс или использовать возвращённые данные. Рассмотрим три основные задачи:

1. Управление состоянием после мутации

В приведённом выше примере мутация обновляет интерфейс, показывая сообщение об успехе. Вы можете использовать onCompleted в useMutation, чтобы передать дополнительные действия после успеха:

const [addUser] = useMutation(ADD_USER, {
  onCompleted: (data) => {
    console.log('User successfully added:', data.addUser);
  },
});

2. Обновление кэша Apollo

Иногда после выполнения мутации нужно обновить локальный кэш Apollo, чтобы данные UI отображались актуально. Например, если мы добавляем пользователя в список:

const [addUser] = useMutation(ADD_USER, {
  update: (cache, { data }) => {
    const newUser = data?.addUser;
    if (newUser) {
      cache.modify({
        fields: {
          users(existingUsers = []) {
            return [...existingUsers, newUser];
          },
        },
      });
    }
  },
});

Беседа с Apollo Cache напоминает диалог с вашим начальником: если вы объясните, что хотите, грамотно – получите результат без проблем.

3. Обработка ошибок

Для обработки ошибок используйте error из возвращаемого объекта:

if (error) {
  alert(`Could not add user: ${error.message}`);
}

Практическое применение

Мутации невероятно полезны для любых операций, связанных с изменением данных. Например:

  1. Добавление нового пользователя, продукта или комментария.
  2. Обновление профиля пользователя.
  3. Удаление ненужных данных.

Такая гибкость особенно полезна в сложных проектах, где клиенту нужно динамически обновлять интерфейс в ответ на действия пользователя. Это также часто встречается в e-commerce и социальных платформах.

1
Задача
Модуль 3: React, 12 уровень, 4 лекция
Недоступна
Отправка запроса на добавление пользователя
Отправка запроса на добавление пользователя
1
Задача
Модуль 3: React, 12 уровень, 4 лекция
Недоступна
Обновление списка пользователей
Обновление списка пользователей
3
Опрос
Введение в GraphQL, 12 уровень, 4 лекция
Недоступен
Введение в GraphQL
Введение в GraphQL
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ