*️⃣Optimistic update

⚡ 1) Теория

circle-info

Optimistic update — это концепция и практика, которая позволяет мгновенно обновлять данные в пользовательском интерфейсе до получения подтверждения от сервера. RTK Query является библиотекой для управления состоянием данных и запросами на основе React.

Когда вы отправляете запрос на сервер для обновления данных с использованием RTK Query, обычный подход состоит в том, чтобы ждать ответа от сервера и затем обновить состояние данных на основе этого ответа. Однако optimistic update позволяет мгновенно обновить состояние данных в пользовательском интерфейсе, даже до получения ответа от сервера.

Когда вы отправляете запрос с optimistic update, RTK Query обновляет состояние данных сразу же после отправки запроса. Это позволяет обновить пользовательский интерфейс без ожидания ответа от сервера. Если ответ от сервера подтверждает успешное выполнение запроса, состояние данных остается неизменным. Если же ответ сервера указывает на ошибку, RTK Query автоматически обновляет состояние данных, чтобы отобразить фактическое состояние на сервере.

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

Обратите внимание, что использование optimistic update требует аккуратного обращения, чтобы избежать несоответствий между клиентским и серверным состоянием данных в случае ошибок или задержек при выполнении запросов.

⚡ 2) Пример реализации optimistic update

⚡ 2.1) Первым делом давайте поставим fast3g и убедимся, что удаление отрабатывает, уходит 2 запроса (1 за удалением, второй за получением) и только после того как 2 запроса отработали мы получаем результат.

⚡ 2.2) Давайте реализуем optimistic update при удалении карточки

Будем идти пошагово, согласно документации

deleteCard: build.mutation<DeleteCardResponseType, string>({
  query: (id) => {
    return {
      method: "DELETE",
      url: "cards/card",
      params: {
        id,
      },
    };
  },
  async onQueryStarted(
  // 1 параметр: QueryArg - аргументы, которые приходят в query
  id, 
  // 2 параметр: MutationLifecycleApi - dispatch, queryFulfilled, getState и пр.
  { dispatch, queryFulfilled }) {
    const patchResult = dispatch(
      cardsApi.util.updateQueryData(
      // 1 параметр: endpointName, который мы выполняем после удачного первого запроса (invalidatesTags)
      "getCards",
      // 2 параметр: QueryArgFrom - параметры, которые приходят в endpoint выше
       { packId: "112233", page: 1, pageCount: 3 }, 
       // 3 параметр: Коллбек функция. 
       // В данном блоке мы делаем логику, которая должна выполниться синхронно,
       // без необходимости дожидаться ответа от сервера.
       // Говоря проще пишем здесь логику, которую раньше писали в редьюсере,
       // чтобы изменять стейт
       (draft) => {
        const index = draft.cards.findIndex((card) => card._id === id);
        if (index !== -1) draft.cards.splice(index, 1);
      })
    );
    try {
      await queryFulfilled;
    } catch {
      patchResult.undo();
    }
  },
  invalidatesTags: ["Card"],
}),

⚡ 2.3)Теперь давайте расставим дебаггеры и посмотрим что и как у нас отрабатывает

Основное что нужно увидеть, что мы не попадаем внутрь коллбека в котором реализуется синхронная логика удаления карточки и соответственно никакой optimistic update не отрабатывает

Давайте разбираться почему так. И на самом деле понять это не так уж просто, потому что никаких ошибок и подсказок нету. Причина в том, что мы захаркодили {packId: "1112233", page: 1, pageCount: 3 } и хоть они нам не нужны их необходимо обязательно передать, чтобы система заработала.

И опять вопрос, а где их взять. Когда мы удаляем карточку мы передаем только id, но в карточке есть информация и о колоде. Page и page count есть есть в компоненте Cards. В общем погнали изменять код

Давайте еще раз проверим. Поставим debugger, проанализируем. Если все сделали верно, то должно отрабатывать как полагается

🤘Вывод. Optimistic update - хороший подход, но как и все его нужно применять с умом и не ставить везде где попало без нанобности.

Last updated