У меня есть следующая асинхронная функция преобразования:
const loadProject = createAsyncThunk(
'[Project API] Load Project',
async (project: IKProject, { dispatch }) => {
await kProjectService.loadProject(project)
localStorage.setItem(STORAGE_KEY, project)
dispatch(projectActions.setLoadedProject(project))
// Loading & saving the project configuration
const config = await kProjectService.getProjectConfig(project)
dispatch(projectActions.setProjectConfig(config))
}
)
const unLoadProject = createAsyncThunk(
'[Project API] Un Load Project',
async (project: IKProject, { dispatch }) => {
await kProjectService.closeProject(project)
dispatch(projectActions.resetState())
}
)
const refreshProject = createAsyncThunk(
'[Project API] Refresh Project',
async (project: IKProject, { dispatch }) => {
await dispatch(projectActions.unLoadProject(project))
await dispatch(projectActions.loadProject(project))
console.info('After refreshing')
}
)
Сервис проекта:
import { IKProject, IKProjectConfig } from '@/Types'
import { httpService } from './http.service'
function loadProject(project: IKProject): Promise<IKProject> {
return httpService.post(`/project/load`, project)
}
function loadProjectConfig(project: IKProject): Promise<IKProjectConfig> {
return httpService.get(`/project/config`, project)
}
function closeProject(project: IKProject): Promise<unknown> {
return httpService.delete(`/project/${project.name}/close`, project)
}
export const kProjectService = {
loadProject,
loadProjectConfig,
closeProject,
}
Срез проекта выглядит так
const projectSlice = createSlice({
name: '[Project API]',
initialState,
reducers: {
resetState: () => initialState,
setLoadedProject: (state, action: PayloadAction<IKProject | null>) => {
state.kLoadedProject = action.payload
},
setProjectConfig: (
state,
action: PayloadAction<IKProjectConfig | null>
) => {
state.kConfig = action.payload
},
reducers...
},
extraReducers(builder) {
builder
.addCase(projectActions.refreshProject.pending, (state) => {
state.isRefreshing = true
})
.addMatcher(
isAnyOf(
projectActions.refreshProject.rejected,
projectActions.refreshProject.fulfilled
),
(state) => {
state.isRefreshing = false
}
)
},
selectors: {
selectors...
}
})
isRefreshing
в initialState
по умолчанию имеет значение false.
Согласно определенному extraReducers
оно автоматически меняется в зависимости от статуса обещания (функция thunk), теперь проблема, с которой я столкнулся, заключается в том, что когда действие refreshProject
выполнялось, оно разрешалось немедленно, вместо того, чтобы ждать завершения действий другого.
после отладки я вижу, что isRefreshing
меняется с false
-> true
-> false
ПРИМЕЧАНИЕ. Я вижу вывод console.info('After refreshing')
после завершения действия loadProject
, и поэтому я не понимаю, почему переход разрешается немедленно.
Пожалуйста помоги.
🤔 А знаете ли вы, что...
React поддерживает серверный рендеринг (SSR) для улучшения SEO и производительности.
похоже, что действие resetState()
в unLoadProject
вызвало проблему.
решено: https://github.com/reduxjs/redux-toolkit/issues/4528