【问题标题】:react-navigation: Invariant Violation on navigating in push notification using Expo.addListenerreact-navigation:使用 Expo.addListener 在推送通知中导航的不变违规
【发布时间】:2018-09-06 17:42:31
【问题描述】:

当我的应用程序收到推送通知时,它应该使用通知数据中的 routeName 参数导航到相应的屏幕。

这一直有效,直到我按照 react-navigation docs 中描述的 NavigationService 模式抽象了我们的导航,并在反应导航问题 here 中充实了更多内容。

我遇到的问题是from react-navigationInvariant Violation:如果有状态,应该在构造函数中设置

为了解决这个问题,我尝试在 addListener 通话中移动。我已经尝试过 AppcomponentDidMount、AppWithNavigation ref 回调(这似乎是个坏主意)和 NavigationService 的 setContent 方法。

我尝试了使用 NavigationService 的侦听器的变体,并在 App 中直接使用 NavigationActions.navigatestore.dispatch

我的理论是导航容器正在发生变化,但导航工作正常,除非应用程序关闭并收到通知。我什至让它在应用程序打开的情况下工作,在这种情况下它确实移动到右屏幕。

我在这里错过了什么?

监听器如下所示:

Notifications.addListener(({data}: {data: NotificationType}) => {
  const {routeName, params} = data;
  NavigationService.navigate({
    routeName,
    params,
  });
});

NavigationService.js:

import {StackActions, NavigationActions} from 'react-navigation';
import type {NavigationParams, NavigationRoute} from 'react-navigation';

import {LOGOUT} from '../redux/auth';

let _container; // eslint-disable-line

function setContainer(container: Object) {
  _container = container;
}

function reset(routeName: NavigationRoute, params?: NavigationParams) {
  _container.dispatch(
    StackActions.reset({
      index: 0,
      actions: [
        NavigationActions.navigate({
          routeName,
          params,
        }),
      ],
    }),
  );
}

function navigate(routeName: string, params?: NavigationParams) {
  _container.dispatch(
    NavigationActions.navigate({
      routeName,
      params,
    }),
  );
}

function goBack(options) {
  _container.dispatch(NavigationActions.back(options));
}

function getCurrentRoute(): NavigationRoute | null {
  if (!_container || !_container.state.nav) {
    return null;
  }

  return _container.state.nav.routes[_container.state.nav.index] || null;
}

export function logOut() {
  _container.dispatch({type: LOGOUT});
  reset('Welcome');
}

export default {
  setContainer,
  navigate,
  reset,
  goBack,
  logOut,
};

Navigators.js 的一部分

class AppWithNavigationState extends Component {
  render() {
    return (
      <React.Fragment>
        {/* Fix for white icons on white status bar bug on iOS */}
        {!isAndroid && <StatusBar barStyle="dark-content" />}
        <RootStack
          persistenceKey="NavigationState-2"
          ref={navigatorRef => NavigatorService.setContainer(navigatorRef)}
        />
      </React.Fragment>
    );
  }
}

export default AppWithNavigationState;

【问题讨论】:

    标签: react-native push-notification react-navigation expo


    【解决方案1】:

    这是我最终得到的解决方案。不理想,希望尽快升级到 react-navigation 3。我正在使用 renderLoadingExperimental 在加载时渲染 SplashScreen。加载完成后我无法收到通知,因此我在 SplashScreen 中添加了 onUnmount 并在那里处理注册。

    class AppWithNavigationState extends Component {
      render() {
        return (
          <React.Fragment>
            <RootStack
              persistenceKey="NavigationState-2"
              ref={navigatorRef => NavigationService.setContainer(navigatorRef)}
              renderLoadingExperimental={() => (
                <SplashScreen
                  source="RootStack"
                  onUnmount={() => {
                    Notifications.addListener(({data}) => {
                      NavigationService.navigate(data.routeName, data.params);
                      if (Platform.OS === 'android')
                        Notifications.dismissAllNotificationsAsync();
                    });
                  }}
                />
              )}
            />
          </React.Fragment>
        );
      }
    }
    
    export default AppWithNavigationState;
    

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题。我的设置与您的非常相似,问题是我在应用导航器完成启动之前在传奇中进行导航作为副作用。检查您是否使用persistenceKey,如果是,则先前的状态会异步水合,这就是我的问题的原因。 我的主导航器中有一个回调navigationReady,它位于componentDidMount,但我认为我必须将其移至实际屏幕以避免该问题。目前我找不到合适的方式来订阅容器在恢复所有内容后调度的操作Navigation / INIT

      【讨论】:

      • 谢谢,这与我在启动前的问题副作用非常相似。我通过在等待启动完成的启动画面中添加onUnmount 来解决这个问题。将发布代码...
      猜你喜欢
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      • 2019-06-07
      相关资源
      最近更新 更多