Я создал фрагмент API следующим образом:
export const authSlice = createApi({
reducerPath: "auth",
baseQuery: fetchBaseQuery({
baseUrl: resolveApiBaseUrl(),
prepareHeaders(headers) {
headers.set("Content-Type", "application/json")
headers.set("X-XSRF-TOKEN", <string>resolveUserToken())
return headers
}
}),
endpoints(builder) {
return {
login: builder.mutation<GymAppResponse, Login>({
query: (payload) => ({
url: "/login",
method: "POST",
body: payload
}),
})
}
})
export const {
useLoginMutation,
} = authSlice
Я получаю токен пользователя после входа в систему и сохраняю его в localStorage, чтобы ограничить доступ пользователей к некоторой части моего приложения.
redux toolkit
для взаимодействия с userToken
, и в качестве состояния по умолчанию для userToken я хочу использовать значение localStorage. Поэтому я не хочу писать код в своем компоненте для проверки localStorage и выполнения необходимой логики. Я хочу использовать redux, поэтому, когда значение userToken
обновится в localStorage, Redux автоматически обновит компонент для меня, используя useEffect(() => {...}, userTokenWhichRetrivedFromRedux)
.mutation
и комбинировать его с набором инструментов Redux! Раньше я использовал redux-saga
, который называл redux actions
после success
или fail
запроса/ответа.Вопрос: вот и спрашиваю у всех знающих:
redux-persist
активно не поддерживается, и мне приходится прагматично использовать localStorage. Есть ли пакет или лучшая практика для обработки данных, которые нам нужно сохранить после вызова API?🤔 А знаете ли вы, что...
С React можно работать с данными через HTTP-запросы, используя библиотеки, такие как Axios или Fetch API.
Если я правильно понял, вам нужно добиться двух вещей:
В первой части, я думаю, вы можете добиться этого с помощью утилиты onQueryStarted, которая позволяет вам дождаться завершения запроса на вход, а также дает вам доступ к функции отправки, чтобы вы могли выполнять другие действия с любым другим фрагментом. Обновлено: Теперь, когда я увидел ответ Фрая - да, лучшим решением было бы сопоставление события выполнения запроса с дополнительным редуктором.
Для второй части это может быть немного сложнее, но однажды я заставил его работать, используя событие хранения . По сути, добавьте прослушиватель событий для локального хранилища где-нибудь на верхнем уровне вашего приложения, а затем обновляйте токен каждый раз, когда событие запускается, т. е. используя то же действие, что и на предыдущем шаге, для первоначального заполнения локального хранилища.
Вы можете найти соответствующие примеры здесь, в разделе «примеры» RTK Query
Насколько я понимаю, вы хотите настроить состояние Redux в результате мутации. В этом случае самым простым способом сделать это будет добавление extraReducer
для выполнения действия мутации к вашему фрагменту.
Что касается redux-persist: эта библиотека в значительной степени «закончена» несколько лет назад — она не требует активного обслуживания, чтобы быть полезной, особенно учитывая ее подключаемый характер. Вы должны быть в порядке, используя это.
Вот как я это сделал в аналогичном случае использования:
export const authSlice = createSlice({
name: "auth",
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addMatcher(authApi.endpoints.login.matchFulfilled, (state, action) => {
state.user = action.payload;
})
.addMatcher(authApi.endpoints.logout.matchFulfilled, (state, action) => {
state.user = null;
});
},
});
Вы также можете использовать createListenerMiddleware для доступа к срезу состояния и обеспечения обратного вызова, который будет выполняться на основе matchers
const authListenerMiddleware = createListenerMiddleware();
authListenerMiddleware.startListening({
matcher: isAnyOf(
authApi.endpoints.login.matchFulfilled,
authApi.endpoints.logout.matchFulfilled
),
effect: (action, listenerApi) => {
if (action.meta.arg.endpointName === "login") {
const user = listenerApi.getState().auth.user;
localStorage.setItem(AUTHENTICATED_USER, JSON.stringify(user));
}
if (action.meta.arg.endpointName === "logout") {
localStorage.removeItem(AUTHENTICATED_USER);
}
},
});