Redux Toolkit w / TS: каков рекомендуемый подход для отправки двух последовательных асинхронных последовательных действий

#javascript #reactjs #typescript #redux #redux-toolkit

#javascript #reactjs ( реакция ) #typescript #сокращение #redux-toolkit

Вопрос:

Недавно я столкнулся с этой проблемой, когда попытался использовать две разные версии API. Логика такова, что если v2 API выдает мне ошибку 404, то я бы попробовал v1 , если ошибок нет, я бы использовал результаты из v2

Вот моя попытка: я создал два отдельных действия async thunk для каждой версии, а затем создал async thunk, в котором я отправляю оба действия.

 export const getV2LoggingOptions = createAsyncThunk(
  "settings/getV2LoggingOptions",
  async () => {
    return sdkClient.getV2LoggingOptions().promise();
  }
);

export const getV1LoggingOptions = createAsyncThunk(
  "settings/getV1LoggingOptions",
  async () => {
    return sdkClient.getV1LoggingOptions().promise();
  }
);

export const getLoggingOptions = createAsyncThunk(
  "settings/getLoggingOptions",
  async (arg, thunkApi) => {
    let response = await thunkApi.dispatch(getV2LoggingOptions());
    if (response.error) {
      if (
        response.error.statusCode === "404"
      ) {
        response = await thunkApi.dispatch(getV1LoggingOptions());
      }

      throw response.error;
    }

    return response.payload;
  }
);
  

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

  1. Я не знаю, как я могу правильно ввести этот ответ, как в let response = await thunkApi.dispatch(getV2LoggingOptions()); .
  2. кроме того, error свойство внутри response (если v2 вызов не удался) не содержит statusCode свойства. поэтому я не могу это прочесть. Это действительно сбивает меня с толку относительно того, почему он не содержит statusCode

Тогда другим подходом было бы просто создать один асинхронный блок и вызвать две версии внутри напрямую

 export const getLoggingOptions = createAsyncThunk(
  "settings/getLoggingOptions",

  async () => {
    let response;
    try {
      response = await sdkClient.getV2LoggingOptions().promise();
    } catch (error) {
      if (
        error.statusCode === "404"
      ) {
        response = await sdkClient.getV1LoggingOptions().promise();
      }
      throw error;
    }

    return response;
  }
);
  

Похоже, это тоже работает. но проблемы в том, что я все еще не уверен, как ввести response здесь.

API действительно предлагает ввести текст для своего ответа. GetV1LoggingOptionsResponse и GetV2LoggingOptionsResponse еще . но я не уверен, следует ли мне вводить ответ как

 let response: GetV1LoggingOptionsResponse | GetV2LoggingOptionsResponse
  

с тех пор я могу прочитать только перекрывающуюся часть этих двух типов из ответа.

также во втором подходе statusCode отсутствует error то, что попало в catch предложение.

Ответ №1:

Поскольку оба API имеют разные возвращаемые значения, они, вероятно, должны быть разными asyncThunks, и вы должны обрабатывать их действия отдельно. Кроме того, вы должны выполнить обработку ошибок (включая выбрасывание) внутри соответствующих asyncThunks, поскольку это приведет к rejected действию, которое вы можете обработать в редукторе.

Как только у вас появятся эти два asyncThunks, нет причин для третьего asyncThunk, который представит свои собственные действия жизненного цикла, которые вам действительно не нужны, поскольку это, по сути, просто объединение двух других.

Напишите нормальный стук:

 
const getLogginOptions = () => async (dispatch) => {
  let result = await dispatch(getV2LoggingOptions());
  if (getV2LoggingOptions.rejected.match(result)) {
    result =  await dispatch(getV1LoggingOptions());
  }
  return resu<
}