Вопрос или проблема
Когда я выхожу, появляется всплывающее окно для подтверждения. Когда я на него нажимаю и выхожу из сеанса, все в порядке. Проблема в том, что когда я регистрируюсь или вхожу снова, (isLogouting и isOpeLogoutDialogue) не меняются на ложь. Я предоставляю весь код конфигурации для Redux Toolkit.
import { createSlice } from "@reduxjs/toolkit";
import GlobalReducer from "./GlobalReducer";
import GlobalStates from "./GlobalStates";
const GlobalSlice = createSlice({
name: "global",
initialState: GlobalStates,
reducers: GlobalReducer,
});
export default GlobalSlice.reducer;
export const {
handleOpenLogoutDialogue,
handleCloseLogoutDialogue,
handleLoggedOut,
} = GlobalSlice.actions;
const GlobalStates = {
isOpeLogoutDialogue: false,
isLogOuting: false,
};
export default GlobalStates;
import { router } from "@inertiajs/react";
const GlobalReducer = {
handleLoggedOut(state, action, dispatch) {
state.isLogOuting = true;
router.post(route("logout"), {
onFinish: () => {
state.isLogOuting = false;
state.isOpeLogoutDialogue = false;
},
});
},
handleOpenLogoutDialogue(state, action) {
state.isOpeLogoutDialogue = true;
},
handleCloseLogoutDialogue(state, action) {
state.isOpeLogoutDialogue = false;
},
};
export default GlobalReducer;
import { configureStore } from "@reduxjs/toolkit";
import AuthReducer from "./Slices/Auth/AuthSlice";
import GlobalReducer from "./Slices/Global/GlobalSlice";
const store = configureStore({
reducer: {
auth: AuthReducer,
global: GlobalReducer,
}
});
export default store;
Ответ или решение
Проблема с использованием onFinish в Redux Toolkit с Inertia.js при выходе из системы
При работе с Redux Toolkit и Inertia.js в приложении, которое управляет состоянием аутентификации, может возникнуть проблема, когда значение isLogouting
и isOpeLogoutDialogue
не сбрасываются в false
после повторной аутентификации. Ниже приведены рекомендации по решению данной проблемы, а также пояснения к коду, чтобы лучше понять логику работы.
Анализ проблемы
-
Неправильная обработка состояния: В вашей функции редьюсера
handleLoggedOut
для выхода из системы состояниеisLogOuting
устанавливается вtrue
, и вы ожидаете, что после завершения запроса вonFinish
оно будет сброшено вfalse
. Однако из-за особенностей работы сonFinish
, состояние может не обновляться, как вы ожидаете. -
Контекст выполнения onFinish: Важно понимать, что
onFinish
вызывается после завершения асинхронной операции. Следовательно, если редьюсер вызван заново, вы можете столкнуться с тем, что состояние не обновилось, как ожидалось. -
Ошибки при экспортировании: В вашем коде есть несколько ошибок, связанных с экспортом и импортом компонентов:
export default GlobalStates;
должен быть в файле, где вы определяетеGlobalStates
, а не в момент его использования в редьюсере.
Рекомендованное решение
Давайте изменим ваш код для корректного управления состоянием при использовании Inertia.js:
const GlobalStates = {
isOpeLogoutDialogue: false,
isLogOuting: false,
};
const GlobalReducer = {
handleLoggedOut(state, action) {
if (state.isLogOuting) return; // Предотвращаем повторный выход
state.isLogOuting = true;
router.post(route("logout"), {
onFinish: () => {
state.isLogOuting = false;
state.isOpeLogoutDialogue = false;
},
});
},
handleOpenLogoutDialogue(state) {
state.isOpeLogoutDialogue = true;
},
handleCloseLogoutDialogue(state) {
state.isOpeLogoutDialogue = false;
},
};
// Создайте слайс
const GlobalSlice = createSlice({
name: "global",
initialState: GlobalStates,
reducers: GlobalReducer,
});
export default GlobalSlice.reducer;
export const {
handleOpenLogoutDialogue,
handleCloseLogoutDialogue,
handleLoggedOut,
} = GlobalSlice.actions;
// Настройка стора
const store = configureStore({
reducer: {
auth: AuthReducer,
global: GlobalSlice.reducer, // Убедитесь, что используете редьюсер из GlobalSlice
}
});
export default store;
Объяснения
-
Предотвращение повторного выхода: Добавлено условие
if (state.isLogOuting) return;
вhandleLoggedOut
, чтобы избежать несанкционированных вызовов, если операция уже выполняется, что может привести к ошибкам изменения состояния. -
Правильный экспорт редьюсера: Убедитесь, что вы экспортируете правильно созданный редьюсер глобального состояния (
GlobalSlice.reducer
) при настройке Redux Store. -
Использование Inertia.js: Убедитесь, что ваш
router.post
корректно настроен и, что все маршруты соответствуют конфигурации сервера.
Заключение
Ошибка с изменением состояния при повторной аутентификации может быть связана с асинхронностью действий и неправильным управлением состоянием в редьюсере. Следуя предложенным рекомендациям и исправлениям, вы сможете устранить проблему и обеспечить корректное поведение вашего приложения.
Если у вас возникнут дополнительные вопросы или потребуется разъяснение, не стесняйтесь обращаться за помощью.