#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;
}
);
Я думаю, что этот подход работает. но не уверен, что это лучший способ сделать это. Прямо сейчас есть пара проблем с таким подходом:
- Я не знаю, как я могу правильно ввести этот ответ, как в
let response = await thunkApi.dispatch(getV2LoggingOptions());
. - кроме того,
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<
}