[英]How to Navigate from a functional component, from a screen in a tab navigator, where that tab navigator is nested in a parent stack navigator
[英]Navigate to root screen from nested stack navigator
我是新来的,并试图自己学习,我在将用户从嵌套的 stck 导航器屏幕导航回根屏幕时遇到了问题。
这是我的一些课程:-
index.android.js :-
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
StatusBar,
View
} from 'react-native';
import {LoginStack} from './login/loginregisterrouter';
import {StackNavigator } from 'react-navigation';
class reactNavigationSample extends Component {
render(){
return (
<LoginStack/>
);
}
}
AppRegistry.registerComponent('MssReactDemo', () => reactNavigationSample);
登录注册路由器:-
import React from 'react';
import {StackNavigator } from 'react-navigation';
import LoginScreen from './LoginScreen';
import RegisterScreen from './RegisterScreen';
import NavigationContainer from './navigationContainer';
export const LoginStack = StackNavigator({
LoginScreen: {
screen: LoginScreen,
navigationOptions: {
title: 'LoginScreen',
}
},
RegisterScreen: {
screen: RegisterScreen,
navigationOptions: ({ navigation }) => ({
title: 'RegisterScreen',
}),
},NavigationContainer: {
screen: NavigationContainer,
navigationOptions: ({ navigation }) => ({
title: 'NavigationContainer', header: null,
}),
},
});
导航容器.js :-
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
StatusBar,
View
} from 'react-native';
import {EasyRNRoute,} from '../parent';
import {StackNavigator } from 'react-navigation';
export default class NavigationContainer extends Component {
render(){
return (
<EasyRNRoute/>
);
}
}
parent.js :-
import React, { Component } from 'react';
import {
StyleSheet,
Text,
StatusBar,
View
} from 'react-native';
import App from './app';
import DrawerMenu from './Drawer/drawer-toolbar-android';
import BookmarkView from './Pages/bookmark';
import ClientView from './Pages/client';
import InfoView from './Pages/info';
import SettingsView from './Pages/setting';
import { DrawerNavigator, StackNavigator } from 'react-navigation';
export const stackNavigator = StackNavigator({
Info: { screen: InfoView },
Settings: {screen: SettingsView },
Bookmark: {screen: BookmarkView },
Connections: {screen: ClientView},
}, {
headerMode: 'none'
});
export const EasyRNRoute = DrawerNavigator({
Home: {
screen: App,
},
Stack: {
screen: stackNavigator
}
}, {
contentComponent: DrawerMenu,
contentOptions: {
activeTintColor: '#e91e63',
style: {
flex: 1,
paddingTop: 15,
}
}
});
抽屉工具栏-android.js :-
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
StatusBar,
View
} from 'react-native';
import { NavigationActions } from 'react-navigation'
import { COLOR, ThemeProvider, Toolbar, Drawer, Avatar } from 'react-native-material-ui';
import Container from '../Container';
import LoginScreen from '../login/LoginScreen';
const uiTheme = {
palette: {
primaryColor: COLOR.green500,
accentColor: COLOR.pink500,
},
toolbar: {
container: {
height: 70,
paddingTop: 20,
},
},
avatar: {
container: {
backgroundColor: '#333'
}
}
};
export default class DrawerMenu extends Component {
constructor(props, context) {
super(props, context);
this.state = {
active: 'people',
};
}
handleLogoutPress = () => {
// AsyncStorage.setItem('SignedUpuser', '');
this.props
.navigation
.dispatch(NavigationActions.reset(
{
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'LoginScreen'})
]
}));
// this.props.navigation.dispatch(NavigationActions.back());
};
_setInfoActive() {
this.setState({ active: 'info' });
}
render() {
return (
<ThemeProvider uiTheme={uiTheme}>
<Container>
<StatusBar backgroundColor="rgba(0, 0, 0, 0.2)" translucent />
<Toolbar
leftElement="arrow-back"
onLeftElementPress={() => this.props.navigation.navigate('DrawerClose')}
centerElement="Menu"
/>
<View style={styles.container}>
<Drawer>
<Drawer.Header >
<Drawer.Header.Account
style={{
container: { backgroundColor: '#fafafa' },
}}
avatar={<Avatar text={'S'} />}
// accounts={[
// { avatar: <Avatar text="H" /> },
// { avatar: <Avatar text="L" /> },
// ]}
footer={{
dense: true,
centerElement: {
primaryText: 'Siddharth',
secondaryText: 'I am DONE now',
},
}}
/>
</Drawer.Header>
<Drawer.Section
style={{
label: {color: '#0000ff'}
}}
divider
items={[
{
icon: 'bookmark-border', value: 'Bookmarks',
active: this.state.active == 'bookmark',
onPress: () => {
this.setState({ active: 'bookmark' });
this.props.navigation.navigate('Bookmark');
},
},
{
icon: 'people', value: 'Connections',
active: this.state.active == 'Connection',
onPress: () => {
this.setState({ active: 'Connection' });
this.props.navigation.navigate('Connections');
},
},
]}
/>
<Drawer.Section
title="Personal"
items={[
{
icon: 'info', value: 'Info',
active: this.state.active == 'info',
onPress: () => {
this.setState({ active: 'info' });
//this.props.navigation.navigate('DrawerClose');
this.props.navigation.navigate('Info');
},
},
{
icon: 'settings', value: 'Settings',
active: this.state.active == 'settings',
onPress: () => {
this.setState({ active: 'settings' });
this.props.navigation.navigate('Settings');
},
},
{
icon: 'logout', value: 'Logout',
active: this.state.active == 'logout',
onPress: () => {
this.handleLogoutPress();
},
},
]}
/>
</Drawer>
</View>
</Container>
</ThemeProvider>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
header: {
backgroundColor: '#455A64',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
以上是我在我的应用程序中使用的堆栈体系结构,正如您所看到的,我的主屏幕是登录屏幕,我确实可以选择从我的抽屉(侧面菜单)中的应用程序注销。 我真正想要的是,当用户点击注销时,他/她应该被重定向到登录屏幕。 我已经用谷歌搜索了这个并了解了两种方法,但这两种方法都不适合我,可能是我以错误的方式使用它们。 所以我在这里寻求你的帮助。
这两种方法是:-
1)
this.props
.navigation
.dispatch(NavigationActions.reset(
{
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'LoginScreen'})
]
}));
2) this.props.navigation.dispatch(NavigationActions.back());
这个问题对你来说可能看起来很愚蠢,但我真的被困在这一点上,只是想知道我该如何解决这个问题。任何帮助将不胜感激!!!! 提前致谢。
在尝试了几乎所有事情之后,我找到了对我有用的解决方案:
this.props.navigation.popToTop(); // go to the top of the stack
this.props.navigation.goBack(null); // now show the root screen
要求: react-navigation
版本: 1.0.0
目标:从App
TabNavigator 导航到Screen 1
到Screen 2
到Screen N
,然后直接返回App
TabNavigator。
StackNavigator {mode: 'modal'}
TabNavigator
Screen
Screen
Screen
Screen
DismissableStackNavigator
ModalStackScreen
ModalStackScreen
ModalStackScreen
package.json
{
"name": "HelloWorld",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.44.0",
"react-navigation": "^1.0.0"
},
"devDependencies": {
"babel-jest": "20.0.3",
"babel-preset-react-native": "1.9.2",
"jest": "20.0.3",
"react-test-renderer": "16.0.0-alpha.6"
},
"jest": {
"preset": "react-native"
}
}
index.ios.js
(或index.android.js
)import React from 'react'
import {
AppRegistry,
Button,
Text,
View
} from 'react-native'
import {
StackNavigator,
TabNavigator
} from 'react-navigation'
class TabA extends React.Component {
state = {
startScreen: 'none',
returnScreen: 'none'
}
render () {
return (
<View style={{ padding: 40, paddingTop: 64 }}>
<Text style={{ fontSize: 20 }}>{this.constructor.name}</Text>
<Text>startScreen: {this.state.startScreen}</Text>
<Text>returnScreen: {this.state.returnScreen}</Text>
<Button
title="Open ModalScreen"
onPress={() => this.props.navigation.navigate('ModalScreen', {
startScreen: this.constructor.name,
setParentState: (state) => this.setState(state)
})}
/>
<Button
title="Open ModalStack"
onPress={() => this.props.navigation.navigate('ModalStack', {
startScreen: this.constructor.name,
setParentState: (state) => this.setState(state)
})}
/>
</View>
)
}
}
class TabB extends TabA {}
class TabC extends TabA {}
class ModalScreen extends React.Component {
render () {
const {
startScreen,
setParentState
} = this.props.navigation.state.params
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ fontSize: 20 }}>{this.constructor.name}</Text>
<Button
title="Close"
onPress={() => {
setParentState({
startScreen,
returnScreen: this.constructor.name
})
this.props.navigation.goBack()
}}
/>
</View>
)
}
}
const DismissableStackNavigator = (routes, options) => {
const StackNav = StackNavigator(routes, options)
return class DismissableStackNav extends React.Component {
static router = StackNav.router
render () {
const { state, goBack } = this.props.navigation
const screenProps = {
...this.props.screenProps,
dismissStackNav: () => goBack(state.key)
}
return (
<StackNav
screenProps={screenProps}
navigation={this.props.navigation}
/>
)
}
}
}
class ModalStackScreen extends React.Component {
render () {
const screenNumber = this.props.navigation.state.params && this.props.navigation.state.params.screenNumber || 0
const {
startScreen,
setParentState
} = this.props.navigation.state.params
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ fontSize: 20 }}>{this.constructor.name + screenNumber}</Text>
<View style={{
flexDirection: 'row',
justifyContent: 'space-between'
}}>
<Button
title={screenNumber === 0 ? "Close" : "Back"}
onPress={() => this.props.navigation.goBack(null)}
/>
<Button
title="Save"
onPress={() => {
setParentState({
startScreen,
returnScreen: this.constructor.name + screenNumber
})
this.props.screenProps.dismissStackNav()
}}
/>
<Button
title="Next"
onPress={() => this.props.navigation.navigate('ModalStackScreen', {
screenNumber: screenNumber + 1,
startScreen,
setParentState
})}
/>
</View>
</View>
)
}
}
const TabNav = TabNavigator(
{
TabA: {
screen: TabA
},
TabB: {
screen: TabB
},
TabC: {
screen: TabC
}
}
)
const ModalStack = DismissableStackNavigator(
{
ModalStackScreen: {
screen: ModalStackScreen
}
},
{
headerMode: 'none'
}
)
const RootStack = StackNavigator(
{
Main: {
screen: TabNav,
},
ModalScreen: {
screen: ModalScreen,
},
ModalStack: {
screen: ModalStack
}
},
{
mode: 'modal',
headerMode: 'none'
}
)
class App extends React.Component {
render () {
return <RootStack />
}
}
AppRegistry.registerComponent('HelloWorld', () => App)
解决方案是将key: null
添加到重置对象中:
this.props.navigation.dispatch(NavigationActions.reset({
index: 0,
key: null,
actions: [
NavigationActions.navigate({ routeName: 'App'})
]
}))
根据反应导航文档,您可以通过以下方式转到任何堆栈:查看以下链接以获取更多详细信息React-navigation stack action link
1. import { StackActions, NavigationActions } from 'react-navigation';
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'Profile' })],
});
this.props.navigation.dispatch(resetAction);
import { NavigationActions } from 'react-navigation'; const navigateAction = NavigationActions.navigate({ routeName: 'Profile', params: {}, action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }), }); this.props.navigation.dispatch(navigateAction);
(React Navigation 5.x)我遇到了像“ https://reactnavigation.org/docs/en/auth-flow.html ”中的示例那样有条件地呈现屏幕的问题据我了解,这意味着堆栈导航器不是“渲染”,因此无法找到彼此。 我所做的是以下和注销页面:
navigation.replace('SplashScreen')
我的逻辑是:SplashScreen(检查 AsyncStorage 令牌),
if (token){
navigation.navigate('App')
}else{
navigation.navigate('StartScreen')
}
在 StartScreen 中,只需导航到登录或注册,如果登录成功,您将返回应用程序。
作为参考,
function AppBottomNavigator(){
return(
<AppNavigator.Navigator
initialRouteName={'Home'} ...}>
<AppNavigator.Screen name='A' component={ScreenA}/>
<AppNavigator.Screen name='B' component={ScreenB}/>
<AppNavigator.Screen name='C' component={ScreenC}/>
<AppNavigator.Screen name='D' component={ScreenD}/>
<AppNavigator.Screen name='E' component={ScreenE}/>
</AppNavigator.Navigator>
)
}
导出默认应用程序内容...
...return(
<AuthContext.Provider value={authContext}>
<NavigationContainer>
<AuthStack.Navigator screenOptions={{headerShown:false}}>
<>
<AuthStack.Screen name='SplashScreen' component={SplashScreen}/>
<AuthStack.Screen name='StartScreen' component={StartScreen} />
<AuthStack.Screen name='SignIn' component={SignIn} />
<AuthStack.Screen name='Register' component={Register} />
<AuthStack.Screen name='App' component={AppBottomNavigator}/>
</>
</AuthStack.Navigator>
</NavigationContainer>
</AuthContext.Provider>
)
我对此也很陌生,但它有效,所以如果其他人有更安全/更整洁/通用的解决方案,我也很想知道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.