Как изменить стейт слайса из экшена другого слайса в redux toolkit?
У меня React приложение на typeScript. Я использую redux-toolkit. Перешел я на него недавно, ранее пользовался обычным редаксом.
У меня есть два слайса, первый user - он хранит в себе токен и инфу о пользователе. У него также есть два экшена, которые удаляют токен и пользователя из стейта. Второй слайс хранит объект ошибок API. Когда при каком-то запросе приходит от сервера сообщение об ошибке, то оно сразу же отправляется в стейт слайса errors. Для этого в этом слайсе есть экшен addNewError.
Но возникла ситуация, когда при коде ошибки 12 мне надо удалить токен и пользователя. Проверка когда ошибки происходит в экшене addNewError перед тем как сохранить эту ошибку в стейт. Ведь если ошибка имеет код 12, то ее не нужно сохранять в стейт.
Но я не понимаю как вызвать экшены удаления токена и юзера из экшена addNewError. Ведь это совершенно другой слайс.
Вот коды моих слайсов:
UserSlice
import UserStorage from "../../localStorage/userStorage";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "../../store";
import { User } from "./user";
interface UserState {
token: string | null
user: User | null
isLogInLoading: boolean
}
const initialState: UserState = {
token: UserStorage.getToken(),
user: UserStorage.getUser(),
isLogInLoading: false
}
export const UserSlice = createSlice({
name: 'user',
initialState,
reducers: {
setToken: (state, action: PayloadAction<string>) => {
state.token = action.payload
UserStorage.setToken(action.payload)
},
setUser: (state, action: PayloadAction<User>) => {
state.user = action.payload
UserStorage.setUser(action.payload)
},
clearToken: (state) => {
state.token = null
UserStorage.removeToken()
},
clearUser: (state) => {
state.user = null
UserStorage.removeUser()
},
setLogInLoading: (state, action: PayloadAction<boolean>) => {
state.isLogInLoading = action.payload
}
}
})
export default UserSlice.reducer
export const { setToken, setUser, clearToken, clearUser, setLogInLoading } = UserSlice.actions
export const selectToken = (state: RootState) => state.user.token
ErrorsSlice
import { ApiError, ApiWarning } from "../apiResponseModels";
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { v4 as uuidv4 } from 'uuid';
interface ErrorState {
apiError: ApiError | null
warningsChannel: ApiWarning[]
}
const initialState: ErrorState = {
apiError: null,
warningsChannel: []
}
const warningTypeErrorCodes: number[] = [
// Add all error codes which has warning only type
]
export const ErrorSlice = createSlice({
name: 'errors',
initialState,
reducers: {
addNewError: (state, action: PayloadAction<ApiError>) => {
const errorObj = action.payload
if (errorObj.code === 12) {
// здесь надо вызвать экшены clearToken и clearUser, которые находятся в другом слайсе user
}
else if (warningTypeErrorCodes.includes(errorObj.code)) {
const warningObj = {
...errorObj,
fired: false,
localId: uuidv4()
}
state.warningsChannel = [warningObj, ...state.warningsChannel]
} else {
state.apiError = errorObj
}
},
removeError: (state) => {
state.apiError = null
},
deleteOneWarning: (state, action: PayloadAction<ApiWarning>) => {
const { localId } = action.payload
const indexToRemove = state.warningsChannel.findIndex(
(warning) => warning.localId === localId
)
if (indexToRemove !== -1) {
state.warningsChannel = [
...state.warningsChannel.slice(0, indexToRemove),
...state.warningsChannel.slice(indexToRemove + 1),
]
}
},
clearAllWarnings: (state) => {
state.warningsChannel = []
}
}
})
export default ErrorSlice.reducer
export const { addNewError, removeError, deleteOneWarning, clearAllWarnings } = ErrorSlice.actions