Как обрабатывать обещания от действия из React Redux

export const uploadFile = createAsyncThunk(
  "simulation/uploadFile",
  async (filesSelected) => {
    console.info(filesSelected[0].name + " Will be uploaded");

    const formData = new FormData();

    formData.append(filesSelected.name, filesSelected);
    formData.append("dcmFile", filesSelected[0]);
    formData.append("mdfFile", filesSelected[1]);
    formData.append("modelFile", filesSelected[2]);

    const response = await axios
      .post("http://localhost:8000/simulation/start/", formData)
      .then((response) => {
        /**
         * The 'then' method is executed only when the request is successfull.
         */
        console.info(response);
      })
      .catch((err) => {
        /**
         *  The 'catch' method is executed only when the request fails to complete.
         */
        console.info(err);
      });
    console.info(response.statusText);
    return response.statusText;
  }
);
dispatch(uploadFile);

Я хочу дождаться отправки этой отправки, если axios вернет ошибку. Я хочу отправить сообщение пользователю, если все пойдет гладко. Я также хочу отобразить сообщение.

🤔 А знаете ли вы, что...
JavaScript поддерживает работу с куки и хранилищем веб-браузера для сохранения данных на клиентской стороне.


1
52
2

Ответы:

Вы можете окружить отправленное действие try/catch и await развернутым решенным или отклоненным промисом.

Пример:

const handler = async () => {
  try {
    await dispatch(uploadFile).unwrap();
    // success, resolved, display success message popup
  } catch(error) {
    // handle error, display error message popup
  }
};

См. Обработка результатов преобразования для более подробной информации.

Код также смешивает цепочки промисов с async/await, что обычно считается чем-то вроде анти-шаблона. Используйте один или другой, но не оба в большинстве случаев использования.

Пример:

export const uploadFile = createAsyncThunk(
  "simulation/uploadFile",
  async (filesSelected, thunkAPI) => {
    console.info(filesSelected[0].name + " Will be uploaded");

    const formData = new FormData();

    formData.append(filesSelected.name, filesSelected);
    formData.append("dcmFile", filesSelected[0]);
    formData.append("mdfFile", filesSelected[1]);
    formData.append("modelFile", filesSelected[2]);

    try {
      const response = await axios.post("http://localhost:8000/simulation/start/", formData);

      // This is executed only when the request is successful.
      console.info(response.statusText);
      return response.statusText;
    } catch(error) {
      // The 'catch' block is executed only when the request fails to complete.
      console.info(error);
      return thunkAPI.rejectWithValue(error);
    }
  }
);

Решено

Я думаю, что лучшая практика обработки createAsyncThunk ошибок — обрабатывать их в срезе. Поэтому вместо того, чтобы ловить ошибку в вашем действии createAsyncThunk, пусть ошибка произойдет, а затем в срезе она должна выглядеть так:

const initialState = {
    getStatus: {},
    doStatus: {},
};

export const mockSlice = createSlice({
    name: 'mock',
    initialState,
    reducers: {
        resetDoStatus: (state) => {
            state.doStatus = {};
        },
    },
    extraReducers: (builder) => {
        builder
            .addCase(uploadFile.pending, (state) => {
                state.doStatus.pending = true;
            })
            .addCase(uploadFile.rejected, (state, action) => {
                state.doStatus.pending = false;
                state.doStatus.errorMessage = action.error.message;
                state.doStatus.error = true;
            })
            .addCase(
                uploadFile.fulfilled,
                (state) => {
                    state.doStatus.pending = false;
                    state.doStatus.success = true;
                    state.doStatus.successMessage = "Upload success!"
                }
            );
    },
});

export const {
    resetDoStatus: resetMockDoStatus,
} = mockSlice.actions;
export const mockSlice = mockSlice.reducer;

Делая это таким образом, вы можете просто получить ошибку в своем компоненте и отобразить ошибку так, как вам нравится, вы также можете загружать компоненты в соответствии с вашим состоянием и сбрасывать все это, как вам нравится.