Неожиданное поведение диспетчеризации действий в redux

У меня есть следующая асинхронная функция преобразования:

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 и производительности.


73
1

Ответ:

Решено

похоже, что действие resetState() в unLoadProject вызвало проблему.

решено: https://github.com/reduxjs/redux-toolkit/issues/4528