Почему не работает кэш по умолчанию для useMutation?
Есть апишка, которая в аргумент принимает название одной из таблиц апи
В документации написано, что кэш встроен по умолчанию
По крайней мере в useQueryесть свойство keepUnusedDataFor, которое по умолчанию 60 сек.
Что-то похожего для useMutationя не смог найти
Каждый раз при запросе происходит новый запрос на сервер, хотя секунду назад запрос по такому апи уже был
export const rootApi = createApi({ reducerPath: 'root', tagTypes: ['root'], baseQuery: fetchBaseQuery({ baseUrl }), endpoints: (builder) => ({ getTable: builder.mutation({ query: (table) => `${table}` }) }) }); export const { useGetTableMutation } = rootApi |
export const rootApi = createApi({ reducerPath: 'root', tagTypes: ['root'], baseQuery: fetchBaseQuery({ baseUrl }), endpoints: (builder) => ({ getTable: builder.mutation({ query: (table) => `${table}` }) }) }); export const { useGetTableMutation } = rootApi
const [getTable, { data = [], isLoading }] = useGetTableMutation() function handleClick(link: string) { getTable(table) } |
const [getTable, { data = [], isLoading }] = useGetTableMutation() function handleClick(link: string) { getTable(table) }
Как настроить кэш для useMutation?
Дополнительно:
Это противоречит самой логике mutation. Напиши builder.query вместо этого.
- Но мне нужно делать запросы по нажатию кнопки, а query автоматический запускает запрос при рендере
Или как это сделать через builder.query? - MishaXXL, useLazyQuery в помощь. В документации смотри, работает именно по явному вызову.
- chemdev, спасибо, нашел
А mutation получается только для тех случаев, когда нужно исключить кэширование, верно? - chemdev, а сейчас почему кэш не работает? )
export const rootApi = createApi({ reducerPath: 'root', tagTypes: ['root'], baseQuery: fetchBaseQuery({ baseUrl }), endpoints: (builder) => ({ getTable: builder.query({ query: (table) => `${table}`, keepUnusedDataFor: 120, }) }) }); export const { useLazyGetTableQuery } = rootApi
export const rootApi = createApi({ reducerPath: 'root', tagTypes: ['root'], baseQuery: fetchBaseQuery({ baseUrl }), endpoints: (builder) => ({ getTable: builder.query({ query: (table) => `${table}`, keepUnusedDataFor: 120, }) }) }); export const { useLazyGetTableQuery } = rootApi
- MishaXXL, покажи, как ты используешь хук?
- chemdev,
const [getTable, { data = [], isLoading }] = useLazyGetTableQuery() function handleClick(url: string) { getTable(url) } <button onClick={() => handleClick(table.url)}>{table.name}</button>
const [getTable, { data = [], isLoading }] = useLazyGetTableQuery() function handleClick(url: string) { getTable(url) } <button onClick={() => handleClick(table.url)}>{table.name}</button>
- MishaXXL,
useLazyQuery
Returns a tuple with a trigger function, the query result, and last promise info. Similar to useQuery, but with manual control over when the data fetching occurs. Note: the trigger function takes a second argument of preferCacheValue?: boolean in the event you want to skip making a request if cached data already exists.Возвращает кортеж с функцией запуска, результатом запроса и информацией о последнем запросе. Аналогично useQuery, но с ручным управлением, когда делать запрос. Примечание: функция trigger принимает второй аргумент preferCacheValue?: boolean в том случае, если вы хотите пропустить выполнение запроса, если кэшированные данные уже существуют.
- MishaXXL, почитал доку за тебя но в принципе рад, не помнил этих подробностей)
- chemdev, спасибо, я это читал, но думал, что кэш настраивается свойством в апи и наоборот это для принудительного обновления кэша на всякий случай, и все запросы по умолчанию берутся из кэша
- MishaXXL, ну так все и работает с дефолтным хуком. А с ленивым чтобы не было логической несостыковки (вроде ты триггеришь запрос а реального запроса нет), ты должен уже явно сказать смотреть ли кэш.
- chemdev, подскажи пожалуйста, а для чего тогда нужен useMutation, если через useQuery можно все реализовать?
- MishaXXL, ну есть туториал и он небольшой на оф сайте. Там все предельно раскрывается.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Когда вы используете кэширование по умолчанию для useMutation в Apollo Client, вы можете столкнуться с проблемой, когда кэш не работает должным образом. Это может произойти по нескольким причинам, и я расскажу вам, как их исправить.
1. Неправильно настроенный кэш: Убедитесь, что вы правильно настроили кэш для вашего useMutation. Для этого убедитесь, что вы используете правильные опции кэширования при создании useMutation, такие как update и optimisticResponse.
2. Ключи запроса: Проверьте, что ключи запроса для вашего useMutation уникальны. Если ключи запроса не уникальны, Apollo Client не сможет правильно кэшировать результаты запроса.
3. Обновление кэша: Убедитесь, что вы правильно обновляете кэш после выполнения мутации. Для этого вам может потребоваться использовать методы кэширования Apollo Client, такие как writeQuery или writeFragment.
Приведу пример кода на языке программирования PHP, демонстрирующий правильную настройку кэша для useMutation в Apollo Client:
const [addUser, { data }] = useMutation(ADD_USER_MUTATION, { update(cache, { data: { addUser } }) { cache.modify({ fields: { users(existingUsers = []) { const newUserRef = cache.writeFragment({ data: addUser, fragment: gql` fragment NewUser on User { id name email } `, }); return [...existingUsers, newUserRef]; }, }, }); }, });
Этот код показывает, как правильно обновить кэш после выполнения мутации с помощью метода update и функции cache.modify. Убедитесь, что ваш код следует подобному подходу для правильной работы кэша по умолчанию для useMutation в Apollo Client.