在反应导航的V4文档中有一个很好的切换导航器示例:
https://snack.expo.io/@react navigation/auth-flow-v3
我不明白我怎么能把它变成V5的正确方式。这是链接:
https://reactnavigation.org/docs/en/upgrading-from-4.x.html#switch-导航
如能提供任何帮助,我们将不胜感激。
如果您想用V5实现类似"switch"的功能,您需要选择使用新的<Stack.Navigator />
定义。基本上,<Stack.Navigator />
可以有<Stack.Screen />
的子级,只要您明确地在它们之间切换(或将它们设置为null(,它就会在它们之间产生动画。你可以在这里找到更多关于如何做到这一点的文档:https://reactnavigation.org/docs/auth-flow
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的示例。
我想我找到了这个问题的解决方案,它将阻止用户所有不需要的导航,并且仍然保持屏幕之间的平滑过渡。
- 您需要像这样添加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 }],
});
}
- 将ref从navigationService添加到NavigationContainer,如下所示:
<NavigationContainer ref={navigationService.navigationRef}>
<Navigation />
</NavigationContainer>
现在,当您知道需要更改堆栈时,只需调用changeStack,而不是navigation。
我在这里更详细地解释了这个解决方案:更改react navigation v5 中的堆栈