我正在 React Native 应用程序中测试离线行为和错误。我有一个在其父级中显示和隐藏的模态,如下所示:
return (
...
{showTranslationProgress && (
<TranslatingRecipesView
...
setShowTranslationProgress={setShowTranslationProgress}
...
/>
)}
...
)
此模式显示安装进度条,作业完成后该进度条将关闭。它按预期工作,除了模态中最后一个
else
块的情况:
} catch (err) {
setShowTranslationProgress(false);
if (err.message === moreThan20PercentFailedMessage) {
Alert.alert(moreThan20PercentFailedMessage);
} else if (err.message === noInternet) {
Alert.alert(noInternet, noInternetMessage);
} else {
Alert.alert(ErrorCodeOthers);
}
i18n.changeLanguage(prevGlobalLanguageCode);
}
在前两个错误情况下,我抛出一个
new Error()
并且当警报弹出时进度条会隐藏,正如预期的那样。最后一种情况捕获所有其他错误,当它被触发时,进度条不会隐藏,我可以在警报后面看到它。我发现的唯一区别是错误类型是 Axios 错误。尽管即使我只是抛出一个常规错误而不是传递 Axios 错误,它仍然会发生,所以我被难住了。
父级和模式中的所有日志似乎都确认状态正在正确更新。我试过了:
setShowTranslationProgress(false)
。setTimeout
。finally
块并在那里调用 setShowTranslationProgress(false)
。new Error()
中抛出的位置。visible
属性而不是父级中的条件渲染。这里就是错误发生的地方。如果触发“无互联网”块,进度条将按预期隐藏,如果触发其中的 catch 块,则不会。请注意,我已经注释掉了抛出 Axios 错误,而我只是抛出了一个标准错误:
static async getUnitOfMeasureTranslation(
unitOfMeasureList: UnitOfMeasureModel[],
targetLanguage: string
) {
const unitOfMeasureData: any[] = [];
unitOfMeasureList.map((unitOfMeasure) => {
unitOfMeasureData.push({Text: unitOfMeasure.description});
});
const state = await NetInfo.fetch();
if (state.isConnected) {
try {
const response = await this.getTranslation(
unitOfMeasureData,
targetLanguage
);
const translatedData = response.data;
const updatedTranslatedData = unitOfMeasureList.map(
(unitOfMeasure,index) => {
return {
...unitOfMeasure,
description: translatedData[index].translations[0].text,
unique_id: unitOfMeasure.uom_id + '_' + targetLanguage,
language: targetLanguage,
};
}
);
await createData(SchemaNames.UnitOfMeasureTranslationSchema,{
title: 'UnitOfMeasure',
data: updatedTranslatedData,
});
const mergedUnitOfMeasure = await this.mergeUnitOfMeasureTranslation();
return mergedUnitOfMeasure;
} catch(e) {
console.log(`ERROR TRANSLATING UNIT OF MEASURE TO ${targetLanguage}:`,e);
// throw e
throw new Error(translationNoInternetMessage);
}
} else {
throw new Error(noInternet);
}
}
如果我在 axios 请求之前在 try 块内抛出错误,它会按预期工作。如果我紧接着扔一个,它就不会。这让我相信这与请求本身有关,这让我感到困惑。
我不想被代码淹没,因为代码太多了。由于它在大多数情况下都有效,我认为隔离它会是最有帮助的。如果需要,我可以提供更多代码。
这是我发现唯一有帮助的事情。我的理解是,Axios 在抛出错误后继续工作,这有时会压倒 React 的状态更新。这感觉很糟糕,但这就是我能做的一切。有谁了解更多请评论。
} catch (err) {
if (err.message === noInternet) {
setShowTranslationProgress(false);
Alert.alert(noInternet, noInternetMessage);
} else {
// This allows the progress bar to hide. Axios request
// was causing it to stay visible behind the alert.
await new Promise(resolve => setTimeout(resolve, 500));
setShowTranslationProgress(false);
Alert.alert(ErrorCodeOthers);
}
i18n.changeLanguage(prevLanguageCode);
}