重置主屏幕的导航堆栈(React Navigation 和 React Native)
Resetting the navigation stack for the home screen (React Navigation and React Native)
React Navigation 和 React Native 的导航有问题。是关于重置导航和返回主屏幕。
我在 DrawerNavigator 内部构建了一个 StackNavigator,主屏幕和其他屏幕之间的导航正常。但问题是,导航堆栈不断增长。我不确定如何从堆栈中删除屏幕。
例如,当从主屏幕进入设置屏幕,然后进入进入屏幕,最后再次进入主屏幕时,主屏幕在堆栈中有两次。使用后退按钮我不会退出应用程序,而是会再次进入输入屏幕。
再次选择主页按钮时,重置堆栈会很好,但我不知道该怎么做。 Here 有人试图帮助其他人解决类似问题,但解决方案对我不起作用。
const Stack = StackNavigator({
Home: {
screen: Home
},
Entry: {
screen: Entry
},
Settings: {
screen: Settings
}
})
export const Drawer = DrawerNavigator({
Home: {
screen: Stack
}},
{
contentComponent: HamburgerMenu
}
)
这是抽屉屏风的一个简单例子
export default class HamburgerMenu extends Component {
render () {
return <ScrollView>
<Icon.Button
name={'home'}
borderRadius={0}
size={25}
onPress={() => { this.props.navigation.navigate('Home')}}>
<Text>{I18n.t('home')}</Text>
</Icon.Button>
<Icon.Button
name={'settings'}
borderRadius={0}
size={25}
onPress={() => { this.props.navigation.navigate('Settings')}}>
<Text>{I18n.t('settings')}</Text>
</Icon.Button>
<Icon.Button
name={'entry'}
borderRadius={0}
size={25}
onPress={() => { this.props.navigation.navigate('Entry')}}>
<Text>{I18n.t('entry')}</Text>
</Icon.Button>
</ScrollView>
}
}
希望你能帮助我。这是导航的重要组成部分,如果有解决方案那就太好了!
在您的 StackNavigator 和 DrawerNavigator 中,您使用 Home 作为键,我认为它必须是唯一的,这就是它造成问题的原因。您能否尝试将 DrawerNavigator 中的 Home 替换为 Stack。
希望这会有所帮助:)
我是这样做的:
reset(){
return this.props
.navigation
.dispatch(NavigationActions.reset(
{
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Menu'})
]
}));
}
至少用'Home'替换'Menu'。
您可能还想调整 this.props.navigation 以适应您的实施。
In version > 2 follow this:
import { NavigationActions, StackActions } from 'react-navigation';
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'MainActivity' })],
});
this.props.navigation.dispatch(resetAction);
要使用返回,您需要找到与路径关联的唯一键。在你的 navigation reducer 中,你可以搜索现有状态以使用该路径找到堆栈中的第一条路线,获取它的键并将其传递给 Back。然后返回将导航到您提供的路径之前的屏幕。
let key;
if (action.payload) {
// find first key associated with the route
const route = action.payload;
const routeObj = state.routes.find( (r) => r.routeName === route );
if (routeObj) {
key = { key: routeObj.key };
}
}
return AppNavigator.router.getStateForAction( NavigationActions.back( key ), state );
这是我的做法:
import { NavigationActions } from 'react-navigation'
this.props.navigation.dispatch(NavigationActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'ParentStackScreen' })]
}))
The important part is key: null
.
在从子 导航器导航到父 导航器时擦除堆栈。
如果出现此错误,请执行此操作:
对于动画,我使用
// https://github.com/oblador/react-native-animatable
import * as Animatable from 'react-native-animatable'
我只是自己控制所有的动画。通过用 <Animatable.View>
.
包装它们,将它们放在 任何 组件上
答案是 createSwitchNavigator,它不会叠加您的导航。
在主 screen/stack.
的 createSwitchNavigator 中添加您的身份验证 screen/navigator
因此,当您从主页导航到登录时,不会保留堆栈。
了解更多
https://reactnavigation.org/docs/en/auth-flow.htmlLoginStack
对于最新版本的 react-navigation,您应该使用 StackActions 来重置堆栈,这是一段代码:
// import the following
import { NavigationActions, StackActions } from 'react-navigation'
// at some point in your code
resetStack = () => {
this.props
.navigation
.dispatch(StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName: 'Home',
params: { someParams: 'parameters goes here...' },
}),
],
}))
}
弹出操作会将您带回到堆栈中的上一个屏幕。 n 参数允许您指定弹出多少个屏幕。
n - number - 要弹出的屏幕数。
从 'react-navigation' 导入 { StackActions };
const popAction = StackActions.pop({
ñ:1,
});
this.props.navigation.dispatch(popAction);
只需混合上面给出的两种解决方案就可以了,基本上我们必须使用 StackActions 和 key: null。不使用 StackActions,它会抛出一些错误
import { NavigationActions, StackActions } from 'react-navigation';
const resetHandler = () => {
props.navigation.dispatch(StackActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'PatientDetails' })]
}))
};
目前运行良好:
import { NavigationActions, StackActions } from 'react-navigation'
resetStack = () => {
const navigateAction = NavigationActions.navigate({
routeName: 'Home',
params: {},
action: NavigationActions.navigate({ routeName: 'Home' }),
});
props.navigation.dispatch(navigateAction);
}
在文档中找到:https://reactnavigation.org/docs/en/navigation-actions.html#reset
在 React 导航版本中 5.x
您可以在此版本中使用StackActions.replace
import { StackActions } from '@react-navigation/native';
navigation.dispatch(
StackActions.replace('Home', { test: 'Test Params' })
)
完整示例:(在 Snack 中可用)
import * as React from 'react';
import { View, Button, Text } from 'react-native';
import { NavigationContainer, StackActions } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
function SplashScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:25,marginBottom:25}} >SPLASH SCREEN!</Text>
<Button
title="Replace (RESET) with Home"
onPress={() =>
navigation.dispatch(
StackActions.replace('Home', { test: 'Test Params' })
)
}
/>
<View style={{margin:10}}/>
<Button
title="Push Home on the stack"
onPress={() =>
navigation.dispatch(StackActions.push('Home', { test: 'Test Params' }))
}
/>
</View>
);
}
function HomeScreen({ navigation, route }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:25,marginBottom:25}}>Home Screen!</Text>
<Text style={{margin:10}}>{route.params.test}</Text>
<Button
title="Push same screen on the stack"
onPress={() => navigation.dispatch(StackActions.pop(1))}
/>
<View style={{margin:10}}/>
<Button
title="Pop one screen from stack"
onPress={() =>
navigation.dispatch(StackActions.push('Home', { test: 'Test Params' }))
}
/>
<View style={{margin:10}}/>
<Button
title="Pop to top"
onPress={() => navigation.dispatch(StackActions.popToTop())}
/>
</View>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Splash" component={SplashScreen} />
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
React 导航 5.x , 6.x
import { CommonActions } from '@react-navigation/native';
navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'Home' },
{
name: 'Profile',
params: { user: 'jane' },
},
],
})
);
有售
NavigationActions.reset()
似乎是更好的解决方案。我 运行 对其操作的一个问题是选项卡按钮。即使我在组件中明确关闭它们,选项卡仍会显示。如果我使用 navigation.navigate() 而不是通过 reset()
执行此操作,它将正常工作。
SomeComponentScreen.navigationOptions = {
header: null
};
对我有用的这个烦恼的解决方法是连续调用多个 navigate
语句。
navigation.goBack(); // this would pop current item in stack
navigation.navigate({
routeName: 'SomeOtherComponent'
});
我在使用 @react-navigation
时发现了这条路。但是,在尝试已经在 props
中导航的功能组件时,这里有一种编写重置堆栈操作的巧妙方法:
props.navigation.reset({
index: 0,
routes: [{ name: 'Dashboard' }]
})
React 导航6.x
您可以使用 popToTop()
操作来重置您的堆栈。
示例:
import { StackActions } from '@react-navigation/native';
navigation.dispatch(StackActions.popToTop());
反应导航文档:https://reactnavigation.org/docs/stack-actions/#poptotop
这为我解决了问题(React Navigation 5.x)
import {NavigationActions} from 'react-navigation';
navigation.reset(
[NavigationActions.navigate({routeName: 'Profile'})],
0,
);
React Navigation 和 React Native 的导航有问题。是关于重置导航和返回主屏幕。
我在 DrawerNavigator 内部构建了一个 StackNavigator,主屏幕和其他屏幕之间的导航正常。但问题是,导航堆栈不断增长。我不确定如何从堆栈中删除屏幕。
例如,当从主屏幕进入设置屏幕,然后进入进入屏幕,最后再次进入主屏幕时,主屏幕在堆栈中有两次。使用后退按钮我不会退出应用程序,而是会再次进入输入屏幕。
再次选择主页按钮时,重置堆栈会很好,但我不知道该怎么做。 Here 有人试图帮助其他人解决类似问题,但解决方案对我不起作用。
const Stack = StackNavigator({
Home: {
screen: Home
},
Entry: {
screen: Entry
},
Settings: {
screen: Settings
}
})
export const Drawer = DrawerNavigator({
Home: {
screen: Stack
}},
{
contentComponent: HamburgerMenu
}
)
这是抽屉屏风的一个简单例子
export default class HamburgerMenu extends Component {
render () {
return <ScrollView>
<Icon.Button
name={'home'}
borderRadius={0}
size={25}
onPress={() => { this.props.navigation.navigate('Home')}}>
<Text>{I18n.t('home')}</Text>
</Icon.Button>
<Icon.Button
name={'settings'}
borderRadius={0}
size={25}
onPress={() => { this.props.navigation.navigate('Settings')}}>
<Text>{I18n.t('settings')}</Text>
</Icon.Button>
<Icon.Button
name={'entry'}
borderRadius={0}
size={25}
onPress={() => { this.props.navigation.navigate('Entry')}}>
<Text>{I18n.t('entry')}</Text>
</Icon.Button>
</ScrollView>
}
}
希望你能帮助我。这是导航的重要组成部分,如果有解决方案那就太好了!
在您的 StackNavigator 和 DrawerNavigator 中,您使用 Home 作为键,我认为它必须是唯一的,这就是它造成问题的原因。您能否尝试将 DrawerNavigator 中的 Home 替换为 Stack。
希望这会有所帮助:)
我是这样做的:
reset(){
return this.props
.navigation
.dispatch(NavigationActions.reset(
{
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Menu'})
]
}));
}
至少用'Home'替换'Menu'。 您可能还想调整 this.props.navigation 以适应您的实施。
In version > 2 follow this:
import { NavigationActions, StackActions } from 'react-navigation';
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'MainActivity' })],
});
this.props.navigation.dispatch(resetAction);
要使用返回,您需要找到与路径关联的唯一键。在你的 navigation reducer 中,你可以搜索现有状态以使用该路径找到堆栈中的第一条路线,获取它的键并将其传递给 Back。然后返回将导航到您提供的路径之前的屏幕。
let key;
if (action.payload) {
// find first key associated with the route
const route = action.payload;
const routeObj = state.routes.find( (r) => r.routeName === route );
if (routeObj) {
key = { key: routeObj.key };
}
}
return AppNavigator.router.getStateForAction( NavigationActions.back( key ), state );
这是我的做法:
import { NavigationActions } from 'react-navigation'
this.props.navigation.dispatch(NavigationActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'ParentStackScreen' })]
}))
The important part is
key: null
.
在从子 导航器导航到父 导航器时擦除堆栈。
如果出现此错误,请执行此操作:
对于动画,我使用
// https://github.com/oblador/react-native-animatable
import * as Animatable from 'react-native-animatable'
我只是自己控制所有的动画。通过用 <Animatable.View>
.
答案是 createSwitchNavigator,它不会叠加您的导航。 在主 screen/stack.
的 createSwitchNavigator 中添加您的身份验证 screen/navigator因此,当您从主页导航到登录时,不会保留堆栈。
了解更多 https://reactnavigation.org/docs/en/auth-flow.htmlLoginStack
对于最新版本的 react-navigation,您应该使用 StackActions 来重置堆栈,这是一段代码:
// import the following
import { NavigationActions, StackActions } from 'react-navigation'
// at some point in your code
resetStack = () => {
this.props
.navigation
.dispatch(StackActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName: 'Home',
params: { someParams: 'parameters goes here...' },
}),
],
}))
}
弹出操作会将您带回到堆栈中的上一个屏幕。 n 参数允许您指定弹出多少个屏幕。
n - number - 要弹出的屏幕数。
从 'react-navigation' 导入 { StackActions };
const popAction = StackActions.pop({ ñ:1, });
this.props.navigation.dispatch(popAction);
只需混合上面给出的两种解决方案就可以了,基本上我们必须使用 StackActions 和 key: null。不使用 StackActions,它会抛出一些错误
import { NavigationActions, StackActions } from 'react-navigation';
const resetHandler = () => {
props.navigation.dispatch(StackActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'PatientDetails' })]
}))
};
目前运行良好:
import { NavigationActions, StackActions } from 'react-navigation'
resetStack = () => {
const navigateAction = NavigationActions.navigate({
routeName: 'Home',
params: {},
action: NavigationActions.navigate({ routeName: 'Home' }),
});
props.navigation.dispatch(navigateAction);
}
在文档中找到:https://reactnavigation.org/docs/en/navigation-actions.html#reset
在 React 导航版本中 5.x
您可以在此版本中使用StackActions.replace
import { StackActions } from '@react-navigation/native';
navigation.dispatch(
StackActions.replace('Home', { test: 'Test Params' })
)
完整示例:(在 Snack 中可用)
import * as React from 'react';
import { View, Button, Text } from 'react-native';
import { NavigationContainer, StackActions } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
function SplashScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:25,marginBottom:25}} >SPLASH SCREEN!</Text>
<Button
title="Replace (RESET) with Home"
onPress={() =>
navigation.dispatch(
StackActions.replace('Home', { test: 'Test Params' })
)
}
/>
<View style={{margin:10}}/>
<Button
title="Push Home on the stack"
onPress={() =>
navigation.dispatch(StackActions.push('Home', { test: 'Test Params' }))
}
/>
</View>
);
}
function HomeScreen({ navigation, route }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{fontSize:25,marginBottom:25}}>Home Screen!</Text>
<Text style={{margin:10}}>{route.params.test}</Text>
<Button
title="Push same screen on the stack"
onPress={() => navigation.dispatch(StackActions.pop(1))}
/>
<View style={{margin:10}}/>
<Button
title="Pop one screen from stack"
onPress={() =>
navigation.dispatch(StackActions.push('Home', { test: 'Test Params' }))
}
/>
<View style={{margin:10}}/>
<Button
title="Pop to top"
onPress={() => navigation.dispatch(StackActions.popToTop())}
/>
</View>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Splash" component={SplashScreen} />
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
React 导航 5.x , 6.x
import { CommonActions } from '@react-navigation/native';
navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'Home' },
{
name: 'Profile',
params: { user: 'jane' },
},
],
})
);
有售
NavigationActions.reset()
似乎是更好的解决方案。我 运行 对其操作的一个问题是选项卡按钮。即使我在组件中明确关闭它们,选项卡仍会显示。如果我使用 navigation.navigate() 而不是通过 reset()
执行此操作,它将正常工作。
SomeComponentScreen.navigationOptions = {
header: null
};
对我有用的这个烦恼的解决方法是连续调用多个 navigate
语句。
navigation.goBack(); // this would pop current item in stack
navigation.navigate({
routeName: 'SomeOtherComponent'
});
我在使用 @react-navigation
props
中导航的功能组件时,这里有一种编写重置堆栈操作的巧妙方法:
props.navigation.reset({
index: 0,
routes: [{ name: 'Dashboard' }]
})
React 导航6.x
您可以使用 popToTop()
操作来重置您的堆栈。
示例:
import { StackActions } from '@react-navigation/native';
navigation.dispatch(StackActions.popToTop());
反应导航文档:https://reactnavigation.org/docs/stack-actions/#poptotop
这为我解决了问题(React Navigation 5.x)
import {NavigationActions} from 'react-navigation';
navigation.reset(
[NavigationActions.navigate({routeName: 'Profile'})],
0,
);