React Native应用程序没有按预期崩溃。

5
我们一直在调查应用程序中的问题,其中只看到白屏,没有崩溃日志。适用于Android和iOS。
问题似乎与使用async/await或promises有关。
我们发现当使用async/await或promises时,可以在本地重现白屏问题。
以下代码可重现该问题(尝试尽可能简化)。在新项目中替换App.js为以下内容:
import React, {Fragment} from 'react';
import {Text} from 'react-native';

class App extends React.Component {
  state = {isMounted: false};

  async componentDidMount() {
    await Promise.resolve(1);
    this.setState({isMounted: true});
  }

  render() {
    if (this.state.isMounted) {
      this.state.isMounted.test();
    }
    return (
      <Fragment>
        <Text>test</Text>
      </Fragment>
    );
  }
}

export default App;

我还在Github上推了一个测试项目
我期望应用程序崩溃,因为isMounted没有包含test方法。
当本地运行时,我得到了预期的红框,说明发生了错误。
TypeError: this.state.isMounted.test is not a function. (In 'this.state.isMounted.test()', 'this.state.isMounted.test' is undefined)

This error is located at:
    in App (at renderApplication.js:40)
    in RCTView (at View.js:35)
    in View (at AppContainer.js:98)
    in RCTView (at View.js:35)
    in View (at AppContainer.js:115)
    in AppContainer (at renderApplication.js:39)

...

但是当运行发布版本时,应用程序不会崩溃,并且也没有报错。这使得我们非常难以找到和修复此类问题,因为我们完全无法看到。如果我注释掉它呢?
await Promise.resolve(1);

在发布版本中,它会像预期的那样崩溃。

React Native 版本:0.60.5

我们错误地认为上述代码会导致应用程序崩溃吗?


你期望 await Promise.resolve(1) 做什么?看起来问题在于 isMounted 没有被设置为 true,这就是为什么它没有崩溃的原因。 - Mike M
不重要的是 await Promise.resolve(1) 会做什么。我只是用它来简化示例。它也可以是对 fetch API 的调用。isMounted 能够正常设置为 true,因为如果我在调试模式下运行它,我会得到红色错误框,并且如果我在发布模式下运行它,我可以在 Xcode 输出窗口中看到以下错误 [error][tid:com.facebook.react.JavaScript] TypeError:this.state.isMounted.test不是一个函数。(在“this.state.isMounted.test()”中,“this.state.isMounted.test”未定义) 问题在于该错误被视为非致命性错误,因此不会崩溃应用程序。 - René Madsen
1个回答

1
我发现error-boundaries是缺失的部分。在根级别实现错误边界允许我们手动将这些错误记录到崩溃处理系统中。
另外一件事,如果你使用redux-saga并且抛出了一个错误,默认情况下似乎会被吞掉。所以如果你想处理这些未捕获的错误,可以在createSagaMiddleware中实现onError选项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接