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
环境
- 已移除未使用的依赖包
| package | version |
|---|---|
| @react-navigation/native | 6.0.14 |
| @react-navigation/drawer | 6.5.1 |
| @react-navigation/material-bottom-tabs | 6.2.5 |
| @react-navigation/stack | 6.3.5 |
| react-native-safe-area-context | 4.4.1 |
| react-native-screens | 3.18.2 |
| react-native-gesture-handler | 2.8.0 |
| react-native-reanimated | 2.13.0 |
| react-native | 0.70.6 |
| node | 16.13.0 |
| npm or yarn | 9.1.2 |
内容的提问来源于stack exchange,提问作者Alix Humbert
相关产品推荐
相关产品推荐

