【问题标题】:Where is placed createSwitchNavigator in react-navigation 5.x for migrating from react-navigation 4 to 5.xreact-navigation 5.x 中的 createSwitchNavigator 放置在哪里,用于从 react-navigation 4 迁移到 5.x
【发布时间】:2020-06-02 08:55:49
【问题描述】:

我正在将 React Native 应用程序从 react-navigation 4 迁移到 5.x,但我找不到哪个包包含 createSwitchNavigation。具体来说,我对身份验证令牌检查部分有疑问。

使用 react-navigation 4 我有:

const switchNavigator = createSwitchNavigator({
  ResolveAuth: ResolveAuthScreen,
  signinFlow: createStackNavigator({
    Signup: SignupScreen,
    Signin: SigninScreen,
  }),
  appFlow: createBottomTabNavigator({
    TrackCreate: TrackCreateScreen,
    trackListFlow: createStackNavigator({
      TrackList: TrackListScreen,
      TrackDetail: TrackDetailScreen
    }),
    Account: AccountScreen,
  })
}, {
  initialRouteName: 'ResolveAuth'
});

然后我有一个包含 ResolveAuthScreen 组件的文件。

import React, { useEffect } from 'react';
import { connect } from 'react-redux';

const ResolveAuthScreen = (props) => {
  useEffect(() => {
    if (!props.token) {
      props.navigation.navigate('loginFlow');
    } else {
      props.navigation.navigate('TrackList');
    }
  }, []);

  return null;
};

const mapStateToProps = (state) => {
  return {
    token: state.auth.token,
  };
};

export default connect(mapStateToProps, null)(ResolveAuthScreen);

其他组件对于这个疑问并不重要。我想知道如何复制相同的 Switch 导航流程。 我想知道如何创建这样的东西:

const Switch = createSwitchNavigator();

export default function App() {
  return (
    <NavigationContainer>
      <Switch.Navigator>
        <Switch.Screen name="ResolveAuth" component={ResolveAuthScreen} />
        <Switch.Screen name="signinFlow" component={SignInFlowScreens} />
        <Switch.Screen name="appFlow" component={AppFlowScreens} />
      </Switch.Navigator>
    </NavigationContainer>
  );
}

【问题讨论】:

    标签: reactjs react-native react-navigation react-navigation-v5


    【解决方案1】:

    为了使迁移更容易,您仍然可以使用 createSwitchNavigator from @react-navigation/compat

    【讨论】:

    • 为我工作。省去了经历 V5 的痛苦,看起来你必须做出很多改变
    【解决方案2】:

    在早期版本的 React Navigation 中,有两种方法可以处理这个问题:

    1. 保留多个导航器并在登录时使用切换导航器将活动导航器切换到不同的导航器(推荐)
    2. 登录时将导航器的状态重置为所需的屏幕

    但是对于 v5,您需要使用上下文。看here看详细例子!

    【讨论】:

    • 这与上下文无关,而是条件定义:“我们将在本指南中使用 React.useReducer 和 React.useContext。但如果您使用的是 Redux 或 Mobx 等状态管理库”
    • 好的,我用你提供的链接做了。正如@satya164 所说,不仅上下文 API 对此有效。我用 Redux 做到了。
    • @Siro_Diaz 如果您的问题已得到解答,请务必接受并投票以供进一步参考。
    【解决方案3】:

    v5 上没有切换导航器。你可以试试下面的代码

    function App({ token }) {
      const [isLoggedIn, setLoggedIn] = useState(false);
    
      useEffect(() => {
        setLoggedIn(!!token);
      }, [token]);
    
      return (
        <NavigationContainer>
          {isLoggedIn ? <AppFlowScreens /> : <SignInFlowScreens /> }
        </NavigationContainer>
      );
    }
    
    const mapStateToProps = (state) => {
      return {
        token: state.auth.token,
      };
    };
    
    export default connect(mapStateToProps, null)(App);
    

    【讨论】:

    • 如果您在 SignInFlowScreens 中,如何导航到 AppFlowsScreens 上的任何屏幕?
    • 我更新了答案。现在 useEffect 监听 token 的变化。每当您将令牌设置为 redux 状态时,它都会显示 AppFlowScreens
    • 我认为这可能比需要的复杂一点 - 而不是 useState 和 useEffect,为什么不只是 const isLoggedIn = !!token
    • 我和你的代码一样。但给了我错误。假设用户未登录然后 {isLoggedIn ? : } 这个条件只会返回 并且如果用户试图从这个屏幕进入 AppFlowScreens 屏幕会报错。
    【解决方案4】:

    我按照官方文档(https://reactnavigation.org/docs/auth-flow/),终于成功了。

    关键部分是用于检查用户是否登录的变量必须是全局的(可从任何屏幕访问)。就我而言,我使用了 Redux。

    这是 App 导航的主要代码,我首先检查是否有来自 AsyncStorage 的令牌,然后转到 tabBar 屏幕(主页、配置文件...)或登录屏幕:

    import React, { useEffect } from 'react';
    import { useDispatch, useSelector } from 'react-redux';
    import { setToken } from '../store/actions/user';
    import AsyncStorage from '@react-native-community/async-storage';
    
    ...
    
    const appNavigator = () => {
    
      const dispatch = useDispatch();
      const user = useSelector(state => state.user);
    
      useEffect(() => {
        const getToken = async () => dispatch(setToken(await AsyncStorage.getItem('token')));
        getToken();
      }, [])
    
      return (
        <NavigationContainer>
            {(user.token == null)
                ? <LoginStackScreen />
                : <AppTabScreens />
            }
        </NavigationContainer>
      ) 
    };
    

    在这种情况下,我在 redux 变量 中管理令牌的状态。因此,在登录屏幕中,我们不需要使用任何导航,例如 'navigation.navigate('Home')'。一旦用户登录并生成新令牌,我们只需要更新 redux 变量:

          //props.navigation.navigate('Home');
          dispatch(setToken(newToken));
    

    这将自动转到主屏幕,无需任何额外导航。

    对于注销,我们只需将这个 redux 变量设置为 null(同样,无需使用 navigation.navigate):

         await AsyncStorage.clear();
         //props.navigation.navigate('Auth');
         dispatch(setToken(null));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      相关资源
      最近更新 更多