react-navigation:使用Expo.addListener在推送通知中导航时的不变违规

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

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

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

我遇到的问题是from react-navigation:不变违规:应该在构造函数中设置如果有状态

为了解决这个问题,我尝试过移动addListener电话。我已经尝试过App componentDidMount,AppWithNavigation引用回调(这看起来像个坏主意),以及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
2个回答
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;

0
投票

我遇到了同样的问题。我的设置与你的设置非常相似,问题是我在应用程序导航器启动之前在传奇中做导航作为副作用。检查你是否使用persistenceKey,如果是这样,之前的状态异步水合,这是我的问题的原因。我的主导航器中有一个回调navigationReady是oncomponentDidMount,但我想我必须将它移到实际的屏幕以避免这个问题。目前我找不到一个正确的方法来订阅恢复所有内容后由容器调度的动作Navigation / INIT

© www.soinside.com 2019 - 2024. All rights reserved.