【问题标题】:React Native Navigation & Error BoundariesReact Native 导航和错误边界
【发布时间】:2018-05-28 02:44:29
【问题描述】:

我正在实施我的第一个 react 本机项目,似乎处理错误的最佳方法是使用应用级错误边界。我正在努力弄清楚我们如何将它与react-native-navigation 整合在一起。当前代码如下所示:

# App.js

...

const startApp = () => {
  Navigation.startSingleScreenApp({
    screen: {
      screen: 'App.Splash',
      navigatorStyle: {
        navBarHidden: true,
      },
    },
  });
};

export function startTabs() {
  registerScreens(store, Provider);
  sagaMiddleware.run(RootSaga);

  loadIcons().then(() => {
    // Start app only if all icons are loaded
    startApp();
  });
}

startTabs();

还有screens.js:

# app/Screens.js

...

export default function registerScreens(store, Provider) {
  Navigation.registerComponent('App.Splash', () => SplashContainer, store, Provider);
  ...
 });

因为Navigation.startSingleScreenApp 不返回组件,我正在努力弄清楚如何在导航器内部或外部立即包装错误边界。我尝试浏览 react-native-navigation 文档,但找不到太多帮助。任何想法表示赞赏。

【问题讨论】:

    标签: react-native react-native-navigation wix-react-native-navigation


    【解决方案1】:

    为了记录,我通过将错误边界包装在父提供程序中来解决这个问题,并将其传递给每个导航器屏幕。例如:

    // ProviderWithErrorBoundary.js
    
    const ProviderWithErrorBoundary = ({ store, children }) => (
      <Provider store={store}>
          <ErrorBoundary>
            {children}
          </ErrorBoundary>
      </Provider>
    );
    

    然后通过传递到我的Screens.js

    // Screens.js
    export default function RegisterScreens(store, Provider) {
      Navigation.registerComponent('App.Home', () => HomeContainer, store, Provider);
    })
    

    希望这对某人有所帮助

    【讨论】:

    • 也不错!我没想到你可以重新定义Provider。我看到的只有一个小限制:所有屏幕都必须使用此自定义 Provider 包装,即使它们没有从中受益。
    【解决方案2】:

    当我有这样的要求时我做了什么,我显示了Root HOC 组件,它包裹了第一个屏幕,而不是实际的第一个屏幕。然后你就可以在Root里面处理错误了,因为它会一直被加载并使用Root组件的this.props.navigator来显示错误,例如使用showModal()

    拥有Root 组件的另一个好处是,您可以非常轻松地从侧边菜单切换显示的根屏幕,无需任何特殊的导航操作。或者你可以实现 splash->login->home 流程,就像我在下面的示例中所做的那样。

    可能是这样的:

    class Root: Component {
      static propTypes = {
        navigator: PropTypes.instanceOf(Navigator).isRequired;
      }
    
      constructor(props) {
        this.state = { 
          content: <Splash navigator={this.props.navigator} onLoadComplete={this.handleLoadComplete} />,
        };
        // Adding network interceptor with handleNetworkError() as callback
      }
      
      handleLoadComplete = () => {
        this.setState({
          content: <Login navigator={this.props.navigator} onLoginComplete={this.handleLoginComplete} />,
        });
      }
      
      handleLoginComplete = () => {
        this.setState({ 
          content: <Home navigator={this.props.navigator} />,
        });
      }
      
      handleNetworkError = (error) => {
        this.props.navigator.showModal(screens.NetworkError, {
          passProps: { error },
        });
      }
      
      render() {
        return this.content;
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

    【讨论】:

      【解决方案3】:

      我最终用我的 ErrorBoundary 组件单独包装了每个屏幕。也许不是最优雅或可扩展的选项,但它快速、肮脏且简单,对于我的用例来说,它是最有意义的。

      【讨论】:

        猜你喜欢
        • 2019-03-16
        • 2018-06-15
        • 1970-01-01
        • 2020-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多