Redux Essentials 22. RTK Query + EntityAdapter
Возвращаемся к EntityAdapter в userSlice. Все оказалось очень просто: при получении данных запроса в
https://codesandbox.io/s/redux-essentials-rtk-query-5-react-junior-b5ebze?file=/src/features/users/usersSlice.js
Возвращаемся к EntityAdapter в userSlice. Все оказалось очень просто: при получении данных запроса в
transformResponse
просто вызываем метод usersAdapter.setAll
, чтобы сохранить в нужном виде. https://codesandbox.io/s/redux-essentials-rtk-query-5-react-junior-b5ebze?file=/src/features/users/usersSlice.js
const usersAdapter = createEntityAdapter();Все селекторы можно вернуть, как было, но потребуется внести несколько изменений в логику извлечения данных из хранилища.
const initialState = usersAdapter.getInitialState();
getUsers: builder.query({
// ...
transformResponse: function (responseData) {
return usersAdapter.setAll(initialState, responseData);
}
})
// получение данных запроса из apiSlice#redux #управлениесостоянием #обменданными #rtkquery #документация #примерыкода
export const selectUsersResult = getUsersEndpoint.select();
// извлечение данных из запроса, если он выполнен
// результат работы entity adapter ({ids, entities}) или undefined
const selectUsersData = createSelector(
selectUsersResult,
function (usersResult) {
return usersResult.data;
}
);
export const {
selectAll: getUsers,
selectById: getUserById
} = usersAdapter.getSelectors(
function(state) {
return selectUsersData(state) ?? initialState;
}
);
CodeSandbox
Redux Essentials. RTK Query 5. React Junior - CodeSandbox
Redux Essentials. RTK Query 5. React Junior by furrycat.web using @reduxjs/toolkit, date-fns, react, react-dom, react-redux, react-router-dom, react-scripts, styled-components
👍2
RTK Query. Query hook: параметры
В хук запроса, сгенерированный для эндпоинта, можно передать параметры:
-
-
Настройки есть следующие:
-
-
-
-
-
-
#обменданными #rtkquery #документация
В хук запроса, сгенерированный для эндпоинта, можно передать параметры:
-
queryArg
(параметр для генерации урла запроса, передается в функцию query
) -
queryOptions
(объект с настройками). Настройки есть следующие:
-
skip
- пропустить выполнение запроса для текущего рендера.-
pollingInterval
- для автоматического перезапроса данных.-
selectFromResult
- позволяет изменить возвращаемое хуком значение (оптимизировано для рендера).-
refetchOnMountOrArgChange
-
refetchOnFocus
- refetch при возвращении фокуса на вкладку браузера.-
refetchOnReconnect
- refetch при восстановлении сетевого соединения, если оно было потеряно.#обменданными #rtkquery #документация
👍1
Redux Essentials 23. Выбор данных из запроса
Теперь займемся страницей пользователя, на которой выводятся отфильтрованные по автору посты.
https://codesandbox.io/s/redux-essentials-rtk-query-6-react-junior-kfzw2t?file=/src/features/users/UserPage.js
Воспользуемся хуком
При любом изменении
#redux #управлениесостоянием #rtkquery #обменданными #документация #примерыкода
Теперь займемся страницей пользователя, на которой выводятся отфильтрованные по автору посты.
https://codesandbox.io/s/redux-essentials-rtk-query-6-react-junior-kfzw2t?file=/src/features/users/UserPage.js
Воспользуемся хуком
useGetPostsQuery
, чтобы получить полный список постов и настройкой selectFromResult
(параметры хука запроса), чтобы отфильтровать статьи по автору.const { postsForUser } = useGetPostsQuery(undefined, {
selectFromResult: function(result) {
return {
...result,
postsForUser: (result.data || []).filter(function(post) {
return post.user === userId
})
}
}
});
При любом изменении
state
массив postsForUser
будет пересоздаваться, вызывая перерендер компонента, поэтому нужно обернуть извлечение данных в мемоизированный селектор.#redux #управлениесостоянием #rtkquery #обменданными #документация #примерыкода
👍1
Трансформация данных запроса: 3 подхода
Мы получаем данные из API в одном виде, но для использования может потребоваться их изменение. Сделать это можно в трех местах:
1. Сразу после получения. Преобразуем ответ с помощью
2. В компоненте. Получаем данные, сохраненные в кеше, и извлекаем из них то, что нужно. Рекомендуется использовать
3. В хуке запроса. Отбираем нужные данные с помощью опции
#redux #rtkquery #обменданными #паттерны
Мы получаем данные из API в одном виде, но для использования может потребоваться их изменение. Сделать это можно в трех местах:
1. Сразу после получения. Преобразуем ответ с помощью
transformResponse
и сохраняем в кеше уже измененные данные. Имеет смысл, если новый формат подходит всем потребителям. Можно сочетать с entity adapter.2. В компоненте. Получаем данные, сохраненные в кеше, и извлекаем из них то, что нужно. Рекомендуется использовать
useMemo
для избежания ненужных перерендерингов. Полезно, если одному компоненту нужны данные в другом формате.3. В хуке запроса. Отбираем нужные данные с помощью опции
selectFromResult
. Полезно, если компоненту нужна только часть данных.#redux #rtkquery #обменданными #паттерны
👍2
Redux Essentials 24. RTK Query. Оптимистичные обновления
Переходим к реакциям на статьи.
https://codesandbox.io/s/redux-essentials-rtk-query-7-react-junior-uzedjr?file=/src/features/api/apiSlice.js
Добавляем эндпоинт-мутацию
После того, как пользователь поставил реакцию, нужно отправить запрос и обновить данные статьи, чтобы показать изменения.
Но ради такого мелкого изменения не хочется по новой запрашивать целый список. Для таких ситуаций можно воспользоваться техникой "оптимистичного обновления".
По умолчанию мы предполагаем, что обновление пройдет успешно, и хотим сразу показать пользователю изменение счетчика. Можно подправить уже сохраненные данные, а если запрос вдруг не выполнится, просто отменить эту правку.
Для эндпоинта можно указать метод
Таким образом, запрос отправляется, но мы не хотим ждать его результата, а хотим внести изменения немедленно. У
Теперь нужно только задиспатчить этот thunk, чтобы изменения отобразились в компоненте.
Если же запрос на сервер (
Осталось только внести изменения в компонент
#redux #управлениесостоянием #rtkquery #обменданными #документация #примерыкода
Переходим к реакциям на статьи.
https://codesandbox.io/s/redux-essentials-rtk-query-7-react-junior-uzedjr?file=/src/features/api/apiSlice.js
Добавляем эндпоинт-мутацию
addReaction
.После того, как пользователь поставил реакцию, нужно отправить запрос и обновить данные статьи, чтобы показать изменения.
addReaction: builder.mutation({
query: function({ postId, reaction }) {},
invalidatesTags: function(result, error, arg) {
return [
{ type: 'Post', id: arg.postId }
];
}
})
Но ради такого мелкого изменения не хочется по новой запрашивать целый список. Для таких ситуаций можно воспользоваться техникой "оптимистичного обновления".
По умолчанию мы предполагаем, что обновление пройдет успешно, и хотим сразу показать пользователю изменение счетчика. Можно подправить уже сохраненные данные, а если запрос вдруг не выполнится, просто отменить эту правку.
Для эндпоинта можно указать метод
onQueryStarted
. Это функция, которая при вызове получит два параметра - arg
и thunkApi
, в котором нас интересуют два метода - dispatch
для отправки экшена и queryFulfilled
- промис отправленного запроса.Таким образом, запрос отправляется, но мы не хотим ждать его результата, а хотим внести изменения немедленно. У
apiSlice
есть свойство utils
, а в нем метод updateQueryData
. Он позволяет изменить ранее сохраненные данные. Для этого нужно указать название эндпоинта, ключ кеширования (если нужно) и собственно функцию для обновления.const patchThunk = apiSlice.util.updateQueryData('getPosts', undefined, function(draft) {
// ... вносим изменения в данные draft
// данные можно мутировать
});
Теперь нужно только задиспатчить этот thunk, чтобы изменения отобразились в компоненте.
const patchResult = thunkApi.dispatch(patchThunk);
Если же запрос на сервер (
queryFulfilled
) не выполнится, патч можно отменить, вызвав метод patchResult.undo()
.Осталось только внести изменения в компонент
ReactionButton
, чтобы он использовал хук новой мутации.#redux #управлениесостоянием #rtkquery #обменданными #документация #примерыкода
👍1
Redux Essentials 25. RTK Query. Потоковое обновление кеша
И наконец, осталось только переделать уведомления.
В реально приложении этот функционал скорее всего будет реализован с помощью сокетов. Получаем исходный список уведомлений, а дальше подписываемся на сокет-канал и ждем новых сообщений.
https://codesandbox.io/s/redux-essentials-rtk-query-7-react-junior-uzedjr?file=/src/features/notifications/notificationsSlice.js
Для демонстрационных целей напишем фейковый сокет-сервер, который будет через некоторый интервал генерировать новые уведомления.
Создание эндпоинта
Создадим новый эндпоинт
Экспортируем хук
Подписка на новые уведомления
У эндпоинта есть метод жизненного цикла
Внутри этого метода мы можем подписаться на сокет-канал.
Метод принимает два параметра:
Последовательность действий:
- ждем, пока выполнится основной запрос (
- подписываемся на сокет-канал, при получении новых уведомлений добавляем их к кешированным ранее данным (
- отслеживаем удаление кеша (
Непрочитанные уведомления
Теперь список уведомлений хранится в
При добавлении новых уведомлений в кеш, нужно добавлять их и в
В
Осталось только в компоненте
#redux #управлениесостоянием #rtkquery #обменданными #документация #примерыкода
И наконец, осталось только переделать уведомления.
В реально приложении этот функционал скорее всего будет реализован с помощью сокетов. Получаем исходный список уведомлений, а дальше подписываемся на сокет-канал и ждем новых сообщений.
https://codesandbox.io/s/redux-essentials-rtk-query-7-react-junior-uzedjr?file=/src/features/notifications/notificationsSlice.js
Для демонстрационных целей напишем фейковый сокет-сервер, который будет через некоторый интервал генерировать новые уведомления.
Создание эндпоинта
Создадим новый эндпоинт
getNotifications
, который будет получать исходный список. Для удобства вынесем его в файл notificationsSlice.js
и подключим с помощью метода apiSlice.injectEndpoints
.Экспортируем хук
useGetNotificatinsQuery
и используем его в компоненте NotificationsList
. Тут ничего нового.Подписка на новые уведомления
У эндпоинта есть метод жизненного цикла
onCacheEntryAdded
. Он вызывается в тот момент, когда эндпоинт добавляется в кеш, то есть для него "бронируется" там место (данные при этом еще не получены).Внутри этого метода мы можем подписаться на сокет-канал.
Метод принимает два параметра:
arg
и thunkApi
. В последнем есть несколько полезных методов и данных:const {
updateCachedData,
cacheDataLoaded,
cacheEntryRemoved,
dispatch
} = thunkApi;
Последовательность действий:
- ждем, пока выполнится основной запрос (
cacheDataLoaded
)- подписываемся на сокет-канал, при получении новых уведомлений добавляем их к кешированным ранее данным (
updateCachedData
)- отслеживаем удаление кеша (
cacheEntryRemoved
), закрываем каналНепрочитанные уведомления
Теперь список уведомлений хранится в
apiSlice
. Но нам еще нужно хранить их состояние (непрочитанные/прочитанные). Используем для этого уже существующий notificationsSlice
, только вместо самих уведомлений поместим туда данные об их состоянии.При добавлении новых уведомлений в кеш, нужно добавлять их и в
notificationsSlice
. Добавление происходит при выполнении базового запроса (экшен extendedApi.endpoints.getNotifications.matchFulfilled
), а также при получении новых данных через сокет. Для второго случая создадим отдельный экшен notificationsReceived
(используем утилитарную функцию createAction
).В
extraReducers
отслеживаем нужные экшены (builder.addMatcher
) и добавляем новые элементы в список.Осталось только в компоненте
NotificationsList
получить состояние уведомлений и отметить их как нужно.#redux #управлениесостоянием #rtkquery #обменданными #документация #примерыкода
CodeSandbox
Redux Essentials. RTK Query 7. React Junior - CodeSandbox
Redux Essentials. RTK Query 7. React Junior by furrycat.web using @reduxjs/toolkit, date-fns, react, react-dom, react-redux, react-router-dom, react-scripts, styled-components
👍1
RTK Query. Резюме
Небольшое подведение итогов по RTK Query после прохождения руководства.
RTK Query работает поверх Redux Toolkit, используя его основные концепции.
Предполагается, что вся работа с API в проекте будет собрана в отдельный слайс, созданный с помощью функции
Эндпоинт может быть запросом (query) или мутацией (mutation).
У каждого эндпоинта есть поле
При необходимости, часть эндпоинтов можно перенести в отдельный файл и подключить к слайсу через
Все полученные данные хранятся в кеше. Если на эндпоинт нет подписок, его кеш через некоторое время сбрасывается.
Каждый эндпоинт можно пометить тегом (строка или объект), который можно инвалидировать (принудительно сбросить кеш и вызвать перезапуск запроса) в другом эндпоинте (уточненные теги).
Для эндпоинта генерируется хук (хуки запросов https://yangx.top/react_junior/342), который можно использовать в компонентах. Результат работы хука помимо данных содержит информацию о статусе запроса (`isFetching`,
Можно работать с эндпоинтами и без хуков, они предоставляют ряд методов (`initiate()`, `select()`) (ручная работа с эндпоинтами).
RTK Query поддерживает оптимистичные обновления кеша, для этого используем метод жизненного цикла
Кроме того, возможно обновление кеша "по необходимости", например, при подписке на сокет-канал (потоковое обновление кеша). Для этого используем метод жизненного цикла
#redux #rtkquery #обменданными
Небольшое подведение итогов по RTK Query после прохождения руководства.
RTK Query работает поверх Redux Toolkit, используя его основные концепции.
Предполагается, что вся работа с API в проекте будет собрана в отдельный слайс, созданный с помощью функции
createApi
. Тут можно настроить, как именно должен выполняться запрос (`baseQuery`), а также указать набор эндпоинтов (`endpoints`).Эндпоинт может быть запросом (query) или мутацией (mutation).
У каждого эндпоинта есть поле
query
, формирующее урл запроса. Полученный ответ можно обработать в методе transformResponse
. Кроме того, можно форматировать данные прямо в компоненте (три подхода к форматированию данных)При необходимости, часть эндпоинтов можно перенести в отдельный файл и подключить к слайсу через
apiSlice.injectEndpoints
(разделение эндпоинтов).Все полученные данные хранятся в кеше. Если на эндпоинт нет подписок, его кеш через некоторое время сбрасывается.
Каждый эндпоинт можно пометить тегом (строка или объект), который можно инвалидировать (принудительно сбросить кеш и вызвать перезапуск запроса) в другом эндпоинте (уточненные теги).
Для эндпоинта генерируется хук (хуки запросов https://yangx.top/react_junior/342), который можно использовать в компонентах. Результат работы хука помимо данных содержит информацию о статусе запроса (`isFetching`,
isLoading
, `isError`). Кроме того, хук может принимать параметры для автоматического перезапроса данных и для выборки нужных данных из кеша (`selectFromResult`) (параметры хука запроса).Можно работать с эндпоинтами и без хуков, они предоставляют ряд методов (`initiate()`, `select()`) (ручная работа с эндпоинтами).
RTK Query поддерживает оптимистичные обновления кеша, для этого используем метод жизненного цикла
onQueryStarted
и метод обновления apiSlice.util.updateQueryData
.Кроме того, возможно обновление кеша "по необходимости", например, при подписке на сокет-канал (потоковое обновление кеша). Для этого используем метод жизненного цикла
onCacheEntryAdded
.#redux #rtkquery #обменданными
Telegram
React Junior
Redux Essentials 16. RTK Query. Выполнение запросов
Проект: https://codesandbox.io/s/redux-essentials-rtk-query-react-junior-lced2j?file=/src/features/api/apiSlice.js
baseQuery
Основная (обязательная) настройка в методе createApi - это baseQuery. Это функция…
Проект: https://codesandbox.io/s/redux-essentials-rtk-query-react-junior-lced2j?file=/src/features/api/apiSlice.js
baseQuery
Основная (обязательная) настройка в методе createApi - это baseQuery. Это функция…
👍4
RTK Query
Освежаю знания об RTK Query
RTK Query - это часть Redux Toolkit, которая предназначена для удобной работы с API. Она собирает все, что относится к API в одном месте и дает нам много приятного синтаксического сахара.
Заводим для API отдельный слайс, где будут лежать все данные, полученные с сервера. Но не обычный слайс, который
Подключить этот api-слайс к стору посложнее, чем обычный, тут нужно и редьюсер добавить, и специальный миддлвар.
В api-слайсе определяем функцию, которая будет осуществлять запросы -
На этом техническая подготовка заканчивается и начинается собственно логика обмена данными - поле
Примечание: можно выполнить запрос и «вручную» без использования хука.
Отправка данных на сервер работает практически так же, как и вытягивание, только эндпоинт нужно немного по-другому оформить (через `builder.mutation`). Хук тоже немного другой.
Самое приятное, что запросы к серверу кешируются, однако кеш иногда приходится сбрасывать. Это можно сделать напрямую руками, с помощью метода
Конечно, api-слайс можно расчленять (injectEndpoints).
RTK Query предлагает продвинутые техники работы с API, например, оптимистичное обновление, когда данные меняются сразу, а запрос выполняется уже в фоне. Еще есть возможность подписаться на источник событий (сокет-канал) , чтобы получать данные из него.
Предыдущее резюме по RTK Query, с большим количество технических подробностей.
#управлениесостоянием #rtkquery #обменданными
Освежаю знания об RTK Query
RTK Query - это часть Redux Toolkit, которая предназначена для удобной работы с API. Она собирает все, что относится к API в одном месте и дает нам много приятного синтаксического сахара.
Заводим для API отдельный слайс, где будут лежать все данные, полученные с сервера. Но не обычный слайс, который
createSlice
, а прокачанный слайс, который createApi
.Подключить этот api-слайс к стору посложнее, чем обычный, тут нужно и редьюсер добавить, и специальный миддлвар.
В api-слайсе определяем функцию, которая будет осуществлять запросы -
baseQuery
.На этом техническая подготовка заканчивается и начинается собственно логика обмена данными - поле
endpoints
. Тут мы получаем builder
и с его помощью (`builder.query`) создаем массив наших эндпоинтов (есть много разных настроек) . Каждый эндпоинт на выходе из слайса создает себе личный хук , который можно дернуть в любом месте приложения. А в этом хуке уже предусмотрена куча удобных поле - data
, isLoading
, error
и т.п. И дополнительно можно закинуть ряд настроек, вроде селектора . То есть вытаскивать данные из API со всеми удобствами мы уже можем. Можно даже сочетать все это дело с EnitityAdapter. Примечание: можно выполнить запрос и «вручную» без использования хука.
Отправка данных на сервер работает практически так же, как и вытягивание, только эндпоинт нужно немного по-другому оформить (через `builder.mutation`). Хук тоже немного другой.
Самое приятное, что запросы к серверу кешируются, однако кеш иногда приходится сбрасывать. Это можно сделать напрямую руками, с помощью метода
refetch
, который есть в хуках. Но лучше настроить зависимости с помощью системы тегов, чтобы RTK Query сбрасывала то, что нужно, самостоятельно. Конечно, api-слайс можно расчленять (injectEndpoints).
RTK Query предлагает продвинутые техники работы с API, например, оптимистичное обновление, когда данные меняются сразу, а запрос выполняется уже в фоне. Еще есть возможность подписаться на источник событий (сокет-канал) , чтобы получать данные из него.
Предыдущее резюме по RTK Query, с большим количество технических подробностей.
#управлениесостоянием #rtkquery #обменданными
Telegram
React Junior
Redux Essentials 16. RTK Query. Создание слайса
RTK Query - это еще один уровень абстракции над абстракциями Redux, позволяющий инкапсулировать работу с API: методы получения/обновления/удаления данных, состояние выполнения запроса, синхронизация состояния…
RTK Query - это еще один уровень абстракции над абстракциями Redux, позволяющий инкапсулировать работу с API: методы получения/обновления/удаления данных, состояние выполнения запроса, синхронизация состояния…
🔥3👍2