在反应本机中反应导航库升级到版本 6 时出现错误

Getting error when react navigation lib upgrade to ver 6 in react native

自从我将 react-navigation 从版本 5.x 升级到 6.x 后,我面临以下问题。应用程序一启动就崩溃。

潜在的罪魁祸首可能在以下文件中,但我已尝试注释掉大部分代码,但我仍然出错,除非我从导航中删除此文件。

网络状态

import React, { useCallback, useEffect, useState } from 'react';
import NetInfo from '@react-native-community/netinfo';
import { NavigationProp, useFocusEffect, useNavigation } from '@react-navigation/core';
import { BackHandler, SafeAreaView, StatusBar, StyleSheet } from 'react-native';
import * as Animatable from 'react-native-animatable';

import { flex1 } from '../../styles/flex';
import { absoluteAll } from '../../styles/position';
import { Colors } from '../../styles';
import { Header } from '../Header';
import { AccountStatus } from '../../components/Alerts';
import { ContentService } from '../../services/content';
import { TEST_IDS } from "../../testIds";

export const NetworkStatus = () => {
   const navigation = useNavigation<NavigationProp<any>>();
  const [showScreen, setShowScreen] = useState(false);

  useEffect(() => {
    const unsubscribeNetInfo = NetInfo.addEventListener(state => {
      setShowScreen(!state.isConnected);
    });

    return () => unsubscribeNetInfo();
  }, [setShowScreen]);

  useEffect(
    () =>
      navigation.addListener('beforeRemove', e => {
        if (!showScreen) {
          return;
        }
        e.preventDefault();
      }),
    [navigation, showScreen]
  );

  useFocusEffect(
    useCallback(() => {
      const onBackPress = () => {
        if (showScreen) {
          return true;
        }
        return false;
      };

      BackHandler.addEventListener('hardwareBackPress', onBackPress);

      return () => BackHandler.removeEventListener('hardwareBackPress', onBackPress);
    }, [showScreen])
  );

  if (showScreen) {
    return (
      <Animatable.View animation={'fadeInUp'} duration={500} style={styles.screen}>
{/* some code here */}
        </SafeAreaView>
      </Animatable.View>
    );
  }

  return null;
};

const styles = StyleSheet.create({
  screen: {
    ...absoluteAll,
    backgroundColor: Colors.White,
  },
});

错误日志

  Error: Couldn't find a navigation object. Is your component inside a screen in a navigator?

This error is located at:
    in NetworkStatus (at navigation/index.js:274)
    in StaticContainer
    in EnsureSingleNavigator (at SceneView.tsx:118)
    in SceneView (at useDescriptors.tsx:210)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:281)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:279)
    in RCTView (at View.js:34)
    in View (at CardSheet.tsx:33)
    in CardSheet (at Card.tsx:557)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:217)
    in AnimatedComponent (at createAnimatedComponent.js:278)
    in AnimatedComponentWrapper (at Card.tsx:536)
    in PanGestureHandler (at GestureHandlerNative.tsx:14)
    in PanGestureHandler (at Card.tsx:530)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:217)
    in AnimatedComponent (at createAnimatedComponent.js:278)
    in AnimatedComponentWrapper (at Card.tsx:526)
    in RCTView (at View.js:34)
    in View (at Card.tsx:520)
    in Card (at CardContainer.tsx:219)
    in CardContainer (at CardStack.tsx:654)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:217)
    in AnimatedComponent (at createAnimatedComponent.js:278)
    in AnimatedComponentWrapper (at src/index.native.tsx:114)
    in Screen (at Screens.tsx:37)
    in MaybeScreen (at CardStack.tsx:647)
    in RCTView (at View.js:34)
    in View (at src/index.native.tsx:145)
    in ScreenContainer (at Screens.tsx:20)
    in MaybeScreenContainer (at CardStack.tsx:566)
    in RCTView (at View.js:34)
    in View (at Background.tsx:13)
    in Background (at CardStack.tsx:564)
    in CardStack (at StackView.tsx:437)
    in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
    in SafeAreaProvider (at SafeAreaProviderCompat.tsx:46)
    in SafeAreaProviderCompat (at StackView.tsx:430)
    in GestureHandlerRootView (at GestureHandlerRootView.android.tsx:26)
    in GestureHandlerRootView (at StackView.tsx:429)
    in StackView (at createStackNavigator.tsx:118)
    in Unknown (at createStackNavigator.tsx:117)
    in StackNavigator (at navigation/index.js:269)
    in MainNavigation (at navigation/index.js:389)
    in EnsureSingleNavigator (at BaseNavigationContainer.tsx:430)
    in BaseNavigationContainer (at NavigationContainer.tsx:132)
    in ThemeProvider (at NavigationContainer.tsx:131)
    in NavigationContainerInner (at navigation/index.js:388)
    in AppNavigation (at App.js:152)
    in RCTView (at View.js:34)
    in View (at App.js:151)
    in RCTView (at View.js:34)
    in View (at lib/index.js:102)
    in UserInactivity (at UserInactivity/index.js:37)
    in RawUserInactivity (created by Connect(RawUserInactivity))
    in Connect(RawUserInactivity) (at App.js:149)
    in PortalProvider (at App.js:148)
    in PersistGate (at App.js:143)
    in Provider (at App.js:142)
    in App (at renderApplication.js:47)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:107)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:134)
    in AppContainer (at renderApplication.js:40), js engine: hermes

更新 NetworkStatus 像这样在 Stack Navigator 中使用

const commonScreenOptions = { gestureEnabled: true, swipeEnabled: true };

const MainNavigation = () => {
  const Stack = createStackNavigator();
  const screenOptions = {
    cardStyle: { backgroundColor },
    ...commonScreenOptions,
    headerShown:"false" 
  };

  return (
    <Stack.Navigator screenOptions={screenOptions} initialRouteName='mainAbc'>
      <Stack.Screen name="mainAbc" options={{headerMode:'screen'}}>
        {props => (
          <>
            <MainABC {...props} />
            <NetworkStatus />
          </>
        )}
      </Stack.Screen>
      <Stack.Screen name="abc">
        {props => (
          <>
            <ABC {...props} />
            <NetworkStatus />
          </>
        )}
      </Stack.Screen>
    </Stack.Navigator>
  );
};

MainNavigation基本上是这样传递给NavigationContainer

 <NavigationContainer ref={props.reference} onStateChange={handleOnStateChange}>
  <MainNavigation />
</NavigationContainer>

导航引用从 App.js 传递到上面 NavigationContainer 就像这样

     <Provider store={store}>
    
...
                <AppNavigation
                  reference={_navigator}
                  onNavigationStateChange={this._handleNavigationStateChange}
                  isContentLoaded={this.state.isContentLoaded}
                />
...
  
      </Provider>

_navigator 来自另一个 class 作为

export let _navigator = React.createRef();

我终于找到了解决办法。

原来是导入的问题。 之前 navigation 6useFocusEffect 可以从 @react-navigation/core 导入,但现在必须从 @react-navigation/native

导入

更改导入解决了问题。