You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Navigation退出状态启动时linking的initialRouteName失效

问题描述

我已按照React Navigation文档实现了认证流程,同时通过NavigationContainer的linking属性实现了通知的Linking机制。

当应用处于运行状态时打开通知(例如链接https://domain/transactions/history),会被重定向到TransactionHistory页面,返回时能回到ChargingStations页面(符合预期);但当应用处于退出状态时执行相同操作,虽然能完成重定向,但无法返回ChargingStations页面,且出现警告:The action GO_BACK was not handled by any navigator。

代码示例

App.tsx

export default class App extends React.Component<Props, State> {
  public state: State;
  public props: Props;
  public centralServerProvider: CentralServerProvider;
  public deepLinkingManager: DeepLinkingManager;
  private appVersion: CheckVersionResponse;
  private readonly navigationRef: React.RefObject<NavigationContainerRef<ReactNavigation.RootParamList>>;
  private readonly appContext;
  private initialUrl: string;

  public constructor(props: Props) {
    super(props);
    this.navigationRef = React.createRef();
    this.appContext = {
      handleSignIn: () => this.setState({isSignedIn: true}),
      handleSignOut: () => this.setState({isSignedIn: false})
    };
    this.state = {
      switchTheme: false,
      navigationState: null,
      showAppUpdateDialog: false,
      isSignedIn: undefined
    };
  }

  public setState = (
    state: State | ((prevState: Readonly<State>, props: Readonly<Props>) => State | Pick<State, never>) | Pick<State, never>,
    callback?: () => void
  ) => {
    super.setState(state, callback);
  };


  public async componentDidMount() {
    // 获取中心服务器
    this.centralServerProvider = await ProviderFactory.getProvider();

    // 初始化通知
    await Notifications.initialize();

    // 检查应用更新
    this.appVersion = await Utils.checkForUpdate();
    // 更新状态
    this.setState({
      showAppUpdateDialog: !!this.appVersion?.needsUpdate,
      isSignedIn: true
    });
  }

  public render() {
    const { switchTheme, showAppUpdateDialog, isSignedIn } = this.state;
    return switchTheme ? (
      <NativeBaseProvider>
        <GestureHandlerRootView style={{ flex: 1 }}>
          {showAppUpdateDialog && (
            <AppUpdateDialog appVersion={this.appVersion} close={() => this.setState({ showAppUpdateDialog: false })} />
          )}
          {isSignedIn == null ?
            <Loading />
            :
            this.createRootNavigator()
          }
        </GestureHandlerRootView>
      </NativeBaseProvider>
    ) : (
      <NativeBaseProvider>
        <View />
      </NativeBaseProvider>
    );
  }

  private buildLinking(): LinkingOptions<ReactNavigation.RootParamList> {
    return (
      {
        prefixes: DeepLinkingManager.getAuthorizedURLs(),
        getInitialURL: () => this.initialUrl,
        subscribe: (listener) => {
          // 监听应用运行时的后台通知
          const removeBackgroundNotificationListener = messaging().onNotificationOpenedApp(async (remoteMessage: Notification) => {
            const canHandleNotification = await Notifications.canHandleNotificationOpenedApp(remoteMessage);
            if (canHandleNotification) {
              this.setState({isSignedIn: true}, () => listener(remoteMessage.data.deepLink));
            }
          });
          return () => {
            removeBackgroundNotificationListener();
          };
        },
        config: {
          screens: {
            AuthNavigator: {
              screens: {
                Login: 'login'
              }
            },
            AppDrawerNavigator: {
              initialRouteName: 'ChargingStationsNavigator', // <-- 希望导航时始终作为第一个页面的初始屏幕
              screens: {
                ChargingStationsNavigator: {
                  initialRouteName: 'ChargingStations',
                  screens: {
                    ChargingStations: 'charging-stations/all'
                  }
                },
                InvoicesNavigator: 'invoices',
                TransactionInProgressNavigator: {
                  screens: {
                    TransactionsInProgress: 'transactions/inprogress'
                  }
                },
                TransactionHistoryNavigator: {
                  screens: {
                    TransactionsHistory: 'transactions/history'
                  }
                }
              }
            }
          }
        }
      }
    );
  }

  private createRootNavigator() {
    const { isSignedIn } = this.state;
    return (
      <AuthContext.Provider value={this.appContext}>
        <SafeAreaProvider>
          <NavigationContainer
            onReady={() => this.onReady()}
            linking={this.buildLinking()}
            ref={this.navigationRef}
            onStateChange={(newState) => this.setState({navigationState: newState})}
            initialState={this.state.navigationState}
          >
            <rootStack.Navigator initialRouteName="AuthNavigator" screenOptions={{ headerShown: false }}>
              {isSignedIn ?
                <rootStack.Screen name="AppDrawerNavigator" children={createAppDrawerNavigator} />
                :
                <rootStack.Screen options={{animationTypeForReplace: 'pop'}} name="AuthNavigator" children={createAuthNavigator} />
              }
            </rootStack.Navigator>
          </NavigationContainer>
        </SafeAreaProvider>
      </AuthContext.Provider>
    );
  }
}
预期行为

希望ChargingStations页面始终作为第一个页面存在,即使从退出状态启动应用。

平台
  • Android
  • iOS
环境
  • 已移除未使用的依赖包
packageversion
@react-navigation/native6.0.14
@react-navigation/drawer6.5.1
@react-navigation/material-bottom-tabs6.2.5
@react-navigation/stack6.3.5
react-native-safe-area-context4.4.1
react-native-screens3.18.2
react-native-gesture-handler2.8.0
react-native-reanimated2.13.0
react-native0.70.6
node16.13.0
npm or yarn9.1.2

内容的提问来源于stack exchange,提问作者Alix Humbert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:45:28