为什么我的 React Native 应用程序不仅在我发出 axios 请求时更新其 UI?

问题描述 投票:0回答:1

我正在 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 错误,它仍然会发生,所以我被难住了。

父级和模式中的所有日志似乎都确认状态正在正确更新。我试过了:

  1. 在捕捉块内的不同位置移动
    setShowTranslationProgress(false)
  2. 将警报放入
    setTimeout
  3. 添加一个
    finally
    块并在那里调用
    setShowTranslationProgress(false)
  4. 将 Axios 错误包裹在
    new Error()
    中抛出的位置。
  5. 不传递 Axios 错误,只是抛出一个正常的错误,就像我在其他情况下所做的那样。
  6. 强制重新渲染父级和模态。
  7. 减少axios请求的超时时间。
  8. 使用模态的
    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 块内抛出错误,它会按预期工作。如果我紧接着扔一个,它就不会。这让我相信这与请求本身有关,这让我感到困惑。

我不想被代码淹没,因为代码太多了。由于它在大多数情况下都有效,我认为隔离它会是最有帮助的。如果需要,我可以提供更多代码。

reactjs react-native error-handling axios state
1个回答
0
投票

这是我发现唯一有帮助的事情。我的理解是,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);
   }
© www.soinside.com 2019 - 2024. All rights reserved.