【问题标题】:Navigation between different screens in react nativeReact Native 中不同屏幕之间的导航
【发布时间】:2021-01-06 21:44:11
【问题描述】:

我一直在开发 React Native 应用程序。该应用程序包含入职和其他屏幕。如果用户第一次打开应用程序,我想显示入职屏幕,如果不是这种情况,则必须通过登录屏幕欢迎用户

const LoadNavigation = () => {
  const { isFirst } = useIsFirstLaunch();

  return isFirst === null ? (
    <AppLoading />
  ) : (
    <AppStack.Navigator headerMode="none">
      {isFirst ? (
        <AppStack.Screen name="Onboarding" component={Onboarding} />
      ) : (
        <AppStack.Screen
          name="Authentication"
          component={AuthenticationNavigator}
        />
      )}
    </AppStack.Navigator>
  );
};

export default LoadNavigation;

export const AuthenticationNavigator = () => {
  return (
    <AuthenticationStack.Navigator headerMode="none">
      <AuthenticationStack.Screen name="Login" component={Login} />
    </AuthenticationStack.Navigator>
  );
};

这可行,但是当我尝试从入职屏幕导航到登录屏幕时,它给了我一个错误。

navigation.navigate("Authentication",{screen:"Login"})

如果用户第一次打开应用程序,当我按下 android 上的后退按钮(它必须退出应用程序)时,我不想从登录屏幕返回到启动屏幕

这样的错误

“带有有效负载 {"name":"Authentication","params":{"screen":"Login"}} 的操作 'NAVIGATE' 未被任何导航器处理。"

编辑: 我也在 isFirst 条件中添加了 AuthenticationNavigator。但是这次如果“isFirst”是真还是假,它也会向我显示登录页面

 return (
    <AppStack.Navigator headerMode="none">
      {isFirst ? (
        <>
          <AppStack.Screen name="Onboarding" component={Onboarding} />
          <AppStack.Screen
            name="Authentication"
            component={AuthenticationNavigator}
          />
        </>
      ) : (
        <>
          <AppStack.Screen
            name="Authentication"
            component={AuthenticationNavigator}
          />
        </>
      )}
    </AppStack.Navigator>
  );
};

【问题讨论】:

    标签: react-native react-navigation


    【解决方案1】:

    我就是这样做的:

    export default function App() {
      const [completedOnboarding, setCompletedOnboarding] = useState(true);
      const [isLoggedIn, setIsLoggedIn] = useState(false);
    
      const isFirstTime = async () => {
        try {
          const value = await AsyncStorage.getItem('first_time');
          if (value === null || value === 'true') {
            setCompletedOnboarding(false);
          } else if (value === 'false') {
            setCompletedOnboarding(true);
          }
        } catch (error) {
          console.log({error});
        }
      };
    
      const onDone = async () => {
        try {
          await AsyncStorage.setItem('first_time', 'false');
          setCompletedOnboarding(true);
        } catch (error) {}
      };
    
      useEffect(() => {
        isFirstTime();
      }, []);
    
      return (
        <>
          {!completedOnboarding ? (
            <OnBoarding onDone={onDone} />
          ) : (
            <NavigationContainer>
              <Stack.Navigator screenOptions={{headerShown: false}}>
                {!isLoggedIn ? (
                  <Stack.Screen
                    name="Auth"
                    component={Auth}
                  />
                ) : (
                  <Stack.Screen name="Home" component={Home} />
                )}
              </Stack.Navigator>
            </NavigationContainer>
          )}
        </>
      );
    }
    

    【讨论】:

    • 谢谢,但我如何使用自定义钩子(如 useIsFirstLaunch())实现您的示例
    • 这是您应该在 App.js 中拥有的 AppContainer。 isFirstTime() 是函数,你有它的代码,你用 useEffect (componentDidMount) 调用它。
    【解决方案2】:

    在您的入职屏幕安装的时间点,由于条件渲染,导航器层次结构中不存在登录名。因此,您无法以编程方式从 Onboarding 屏幕中导航,并引发此错误。

    为了解决这个问题,您应该按照文档here 中的说明专门使用条件路由。您应该使用效果来设置此初始状态,具体取决于用户是否登录/退出、是否需要登录等。这取决于您的身份验证/本地状态管理设置。

    编辑:这也应该解决 Android 上的后退按钮,因为如果您在效果或类似中正确设置条件路由,则应该消除堆栈中的任何先前屏幕。

    【讨论】:

    • 如果你能从我的代码中提供一些代码sn-ps,我会很感激
    最近更新 更多