在react-navigation v5中切换导航器

时间:2020-02-24 07:26:49

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

react-navigation的V4文档中有一个很好的开关导航器示例:

https://snack.expo.io/@react-navigation/auth-flow-v3

我不知道如何将其更改为适合V5的方式。这是链接:

https://reactnavigation.org/docs/en/upgrading-from-4.x.html#switch-navigator

我们将不胜感激。

3 个答案:

答案 0 :(得分:2)

好吧,如果您想在V5中实现类似“开关”的功能,则需要选择使用新的<Stack.Navigator />定义。基本上,<Stack.Navigator />可以有<Stack.Screen />个子节点,并且只要您在它们之间显式切换(或将它们设置为null),它将在它们之间进行动画处理。您可以在此处找到有关如何执行此操作的更多文档:https://reactnavigation.org/docs/auth-flow

答案 1 :(得分:0)

React-Navigation v5中没有createSwitchNavigator。 因此可以实现如下。

App.js

// login flow
const Auth = createStackNavigator();
 const AuthStack =()=> (
    <Auth.Navigator 
        initialRouteName="Login"
        screenOptions={{
          animationEnabled: false
        }}
        headerMode='none'
    >
        <Auth.Screen name="Login" component={LoginScreen} /> 
        <Auth.Screen name="Signup" component={SignupScreen} />
    </Auth.Navigator>
 )

// drawer use only in authenticated screens
const Drawer = createDrawerNavigator();
const DrawerStack = () => (
        <Drawer.Navigator initialRouteName="Home">
            <Drawer.Screen name="Home" component={HomeScreen} />
            <Drawer.Screen name="Settings" component={SettingsScreen} />
            <Drawer.Screen name="Logout" component={LogoutScreen}/>
        </Drawer.Navigator>
)
const RootStack = createStackNavigator();

 class App extends Component {
  constructor() {
    super();
    this.state = {
      loading: true,
      hasToken: false,
    };
  }
 
 componentDidMount(){
    AsyncStorage.getItem('jwtToken').then((token) => {
      this.setState({ hasToken: token !== null,loading:false})
    })
  }

  render() {
    const {loading,hasToken} = this.state;
    
    if (loading) {
      return <WelcomeScreen/>
    } 
   else  {
      return( 
          <NavigationContainer>
             <RootStack.Navigator headerMode="none">
           { !hasToken ? 
              <RootStack.Screen name='Auth' component={AuthStack}/>
           : 
              RootStack.Screen name='App' component={DrawerStack}/>
           }
           </RootStack.Navigator>
          </NavigationContainer>  
      );
    }
  }
}
export default App;

这只是进行身份验证的一种方法。我这里没有使用Redux或React Hooks。您可以在React Navigation v5文档中看到使用React Hooks的示例。

答案 2 :(得分:0)

我想我找到了解决此问题的方法,该方法将阻止用户进行所有不必要的导航,并仍保持屏幕之间的平稳过渡。

  1. 您需要像这样添加 navigation.service.js
import * as React from 'react';

export const navigationRef = React.createRef();

export const navigate = (routeName, params) => {
  navigationRef.current?.navigate(routeName, params);
}

export const changeStack = (stackName) => {
  resetRoot(stackName)
}

const resetRoot = (routeName) => {
  navigationRef.current?.resetRoot({
    index: 0,
    routes: [{ name: routeName }],
  });
}
  1. ref navigationService 添加到 NavigationContainer ,如下所示:
<NavigationContainer ref={navigationService.navigationRef}>
  <Navigation />
</NavigationContainer>

现在,当您知道需要更改堆栈时,只需调用 changeStack 而不是导航即可。

我已经在这里更详细地说明了该解决方案: Change stacks in react-navigation v5