0

在 react-navigation 的 V4 文档中有一个很好的 switch navigator 示例:

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

我不明白如何将其更改为 V5 的正确方式。链接在这里:

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

您能提供的任何帮助将不胜感激。

4

3 回答 3

3

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

于 2020-03-02T19:36:05.793 回答
2

React-Navigation v5中没有createSwitchNavigator。所以它可以如下实现。

应用程序.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 的示例。

于 2020-06-26T15:17:01.640 回答
1

我想我找到了解决这个问题的方法,它可以阻止用户所有不需要的导航,并且仍然保持屏幕之间的平滑过渡。

  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. 像这样将该引用navigationService添加到NavigationContainer
<NavigationContainer ref={navigationService.navigationRef}>
  <Navigation />
</NavigationContainer>

现在,当您知道需要更改堆栈时,只需调用changeStack而不是navigate

我在这里更详细地解释了这个解决方案: Change stacks in react-navigation v5

于 2020-10-26T08:40:35.587 回答