反应本机导航以进行分阶段授权

问题描述 投票:0回答:1
const Stack = createNativeStackNavigator<RootNavigationProps>();

const RootNavigation = () => {
  const {token, logout} = useAuth();
  const dispatch = useDispatch<AppDispatch>();
  const {width} = useWindowDimensions();
  const {auth_user_info, loading} = useSelector(
    (state: RootState) => state.authUserInfoSlice,
  );

  useEffect(() => {
    dispatch(authUserInfoRequest({token})).then((result: any) => {
      if (result.payload.message === 'Unauthenticated.') {
        logout();
      }
    });
  }, [dispatch, logout, token]);


  if (token?.token === undefined) {
    setTimeout(() => {
      console.log('📢 [RootNavigation.tsx:109]', token?.token);

      return (
        <Stack.Navigator
          initialRouteName="Login"
          screenOptions={{
            headerShown: false,
            animation: 'slide_from_right',
          }}>
          <Stack.Screen name="Login" component={Login} />
          <Stack.Screen name="LoginOTP" component={LoginOTP} />
        </Stack.Navigator>
      );
    }, 500);
  }

  const authenticated =
    (token?.token &&
      auth_user_info?.create_account_status === '1' &&
      auth_user_info?.job_category_id === '3') ||
    (token?.token &&
      auth_user_info?.create_account_status === '1' &&
      auth_user_info?.add_car_status === '1');

  const hasTokenNotAuthenticated =
    token?.token &&
    auth_user_info?.add_car_status === '0' &&
    auth_user_info?.create_account_status === '0';

  const registeredButNotCar =
    token?.token &&
    auth_user_info?.add_car_status === '0' &&
    auth_user_info?.create_account_status === '1';

  if (hasTokenNotAuthenticated) {
    return (
      <Stack.Navigator
        initialRouteName={'Register'}
        screenOptions={{
          headerShown: false,
          animation: 'slide_from_right',
        }}>
        <Stack.Screen name="Register" component={Register} />
        <Stack.Screen name="ScannerHomeDriver" component={ScannerHomeDriver} />
        <Stack.Screen
          name="CameraScreenDriver"
          component={CameraScreenDriver}
        />
        <Stack.Screen name="DataDriverLicense" component={DataDriverLicense} />
      </Stack.Navigator>
    );
  } else if (registeredButNotCar) {
    return (
      <Stack.Navigator
        initialRouteName={'ScannerHomeTechnical'}
        screenOptions={{
          headerShown: false,
          animation: 'slide_from_right',
        }}>
        <Stack.Screen
          name="ScannerHomeTechnical"
          component={ScannerHomeTechnical}
        />
        <Stack.Screen
          name="CameraScreenTechnical"
          component={CameraScreenTechnical}
        />
        <Stack.Screen name="DataAuto" component={DataAuto} />
      </Stack.Navigator>
    );
  }

  return (
    <Stack.Navigator
      initialRouteName="Home"
      screenOptions={{
headerShown: false,
        animation: 'slide_from_right',
      }}>
      {authenticated && <Stack.Screen name="Home" component={Home} />}
    </Stack.Navigator>
  );
};

输入时需要检查注册状态,根据它会闪烁并应出现错误。找不到导航器的任何屏幕。您是否将任何屏幕定义为其子屏幕?任何导航器均未处理有效负载 {"name":"Register"} 的操作“NAVIGATE”。这些问题都不存在

第一次登录时,用户注册了一个电话号码并通过了OTP,之后他收到了一个token,此时再次打开程序时,我必须去页面填写数据,所以我有4 个阶段。

我的问题是我可以转到下一页,但不能转到上一页。我必须通过价值观来理解这一切。我们再次打开应用程序。

reactjs react-native navigation stack native
1个回答
0
投票

使用加载状态可能有助于避免在完全确定状态之前进行导航。

  1. 渲染加载屏幕或返回 null,这样就可以防止过早渲染导航器
 if (loading) {
  return <LoadingScreen />;
}
  1. 渲染 Stack.Navigators 时不要使用 setTimeout
 if (token?.token === undefined) {
  console.log('📢 [RootNavigation.tsx:108]', token?.token);
  return (
    <Stack.Navigator
      initialRouteName="Login"
      screenOptions={{
        headerShown: false,
        animation: 'slide_from_right',
      }}>
      <Stack.Screen name="Login" component={Login} />
      <Stack.Screen name="LoginOTP" component={LoginOTP} />
    </Stack.Navigator>
  );
}
  1. 有点不相关,但是:用正确的导航逻辑覆盖所有状态可能性
if (!token?.token || !auth_user_info) {
  return <LoginOrLoadingScreen />; // valid navigator for each case.
} else if (hasTokenNotAuthenticated) {
  ...
}
  1. 始终有后备导航
return (
  <Stack.Navigator
    initialRouteName="DefaultScreen"
    screenOptions={{
      headerShown: false,
      animation: 'slide_from_right',
    }}>
    <Stack.Screen name="DefaultScreen" component={DefaultScreen} />
  </Stack.Navigator>
);

或者至少是这样的:

return (
  <Stack.Navigator
    initialRouteName={authenticated ? "Home" : "FallbackScreen"}
    screenOptions={{
      headerShown: false,
      animation: 'slide_from_right',
    }}
  >
    {authenticated ? (
      // authenticated screen
      <>
        <Stack.Screen name="Home" component={Home} />
      </>
    ) : (
      // fallback screen
      <>
        <Stack.Screen name="FallbackScreen" component={FallbackScreen} />
      </>
    )}
  </Stack.Navigator>
);

我可能以错误的方式理解您的问题,但通过猜测布局和结构,这就是我用来确保导航没有任何问题的方法。 如果没有帮助,请随时分享任何相关代码。 (顺便说一句,干净的写作风格😊)

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