3️⃣Optimistic / pessimistic update

Рассмотри Optimistic update на примере редактирования колоды.

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

circle-info

updateQueryDataarrow-up-right Создатель thunk-экшена в Redux, который при вызове создает и применяет набор объектов JSON diff/patch к текущему состоянию. Это немедленно обновляет состояние Redux с этими изменениями.

Создатель thunk-экшена принимает три аргумента: имя ендпоинта, которую мы обновляем (например, 'getPost'), любые соответствующие аргументы запроса и функцию обратного вызова. Функция обратного вызова получает обёрнутый в Immer черновик текущего состояния и может изменять черновик для соответствия ожидаемым результатам после успешного завершения мутации.

Thunk возвращает объект, содержащий {patches: Patch[], inversePatches: Patch[], undo: () => void}. Патчи и обратные патчи создаются с использованием метода produceWithPatches из Immer.

Это обычно используется как первый шаг в реализации оптимистичных обновлений. Сгенерированные inversePatches можно использовать для отмены обновлений, вызвав dispatch(patchQueryData(endpointName, args, inversePatches)). Альтернативно, можно напрямую вызвать метод undo для достижения того же эффекта.

❗Обратите внимание, что первые два аргумента (endpointName и args) используются для определения, какую существующую запись кэша необходимо обновить. Если существующая запись кэша не найдена, функция обратного вызова updateRecipe не будет запущена.

updateDeck: builder.mutation<DeckResponse, UpdateDeckArgs>({
  invalidatesTags: ['Decks'],
  async onQueryStarted({ cover, id, ...args }, { dispatch, queryFulfilled }) {
    const patchResult = dispatch(
      decksService.util.updateQueryData(
        'getDecks',
        { currentPage: 1, itemsPerPage: 3, maxCardsCount: null, minCardsCount: 0, name: null },
        draft => {
          const itemToUpdateIndex = draft.items.findIndex(deck => deck.id === id)

          if (itemToUpdateIndex === -1) {
            return
          }

          // Object.assign(draft.items[itemToUpdateIndex], args)
          draft.items[itemToUpdateIndex] = { ...draft.items[itemToUpdateIndex], ...args }
        }
      )
    )

    try {
      await queryFulfilled
    } catch (e) {
      patchResult.undo()
    }
  },
  query: ({ cover, id, isPrivate, name }) => {
    // 3
    const formData = new FormData()

    if (name) {
      formData.append('name', name)
    }
    if (isPrivate) {
      formData.append('isPrivate', isPrivate.toString())
    }
    if (cover) {
      formData.append('cover', cover)
    } else if (cover === null) {
      // небходимо для зануления картинки
      formData.append('cover', '')
    }

    return {
      body: formData,
      method: 'PATCH',
      url: `v1/decks/${id}`,
    }
  },
}),

Оптимистичный апдейт работает 🚀 Сделайте title > 30 символов и убедитесь, что произойдет откат к предыдущему значению

  • Но хардкодить аргументы - это такое себе решение. Нужно как то их научиться доставать

1) selectInvalidatedByarrow-up-rightФункция, позволяющая выбрать параметры запроса, которые должны быть признаны недействительными.

2) selectCachedArgsForQueryarrow-up-right Функция, которая может выбирать аргументы для текущих кэшированных запросов.

Все должно отрабатывать 🚀

Добавить карточку использую пессимистичный апдейт нельзя. Будет использовать пессимистичный

Все должно отрабатывать 🚀

Last updated