[英]Resetting the navigation stack for the home screen (React Navigation and React Native)
I've got a problem with the navigation of React Navigation and React Native.我遇到了React Navigation和 React Native 的导航问题。 It is about resetting navigation and returning to the home screen.
这是关于重置导航并返回主屏幕。
I've build a StackNavigator inside of a DrawerNavigator, and the navigation between home screen and other screens is working.我在 DrawerNavigator 中构建了一个 StackNavigator,并且主屏幕和其他屏幕之间的导航正常工作。 But the problem is, that the navigation stack grows and grows.
但问题是,导航堆栈不断增长。 I'm not sure how to remove a screen from the stack.
我不确定如何从堆栈中删除屏幕。
For example when going from the home screen to the settings screen, then to the entry screen and lastly again to the home screen, the home screen is twice in the stack.例如,当从主屏幕进入设置屏幕,然后进入条目屏幕,最后再次进入主屏幕时,主屏幕在堆栈中出现两次。 With the back button I do not get out of the app, but again to the entry screen.
使用后退按钮,我不会退出应用程序,而是再次进入进入屏幕。
When selecting the home button again a reset of the stack would be great, but I don't know how to do this.再次选择主页按钮时,重置堆栈会很棒,但我不知道该怎么做。 Here someone tried to help an other person with a similar problem, but the solution didn't work for me.
在这里,有人试图帮助有类似问题的其他人,但该解决方案对我不起作用。
const Stack = StackNavigator({
Home: {
screen: Home
},
Entry: {
screen: Entry
},
Settings: {
screen: Settings
}
})
export const Drawer = DrawerNavigator({
Home: {
screen: Stack
}},
{
contentComponent: HamburgerMenu
}
)
And this is a simple example of the drawer screen这是抽屉屏幕的一个简单示例
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>
}
}
I hope you can help me.我希望你能帮助我。 This is an essential part of the navigation and a solution would be great!
这是导航的重要组成部分,一个解决方案会很棒!
This is How I do it :这是我的做法:
reset(){
return this.props
.navigation
.dispatch(NavigationActions.reset(
{
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Menu'})
]
}));
}
at least replace 'Menu' with 'Home'.至少将“菜单”替换为“主页”。 You may also want to adapt this.props.navigation to your implementation.
您可能还想根据您的实现调整 this.props.navigation。
In version > 2 follow this:
在版本 > 2 中,请遵循以下步骤:
import { NavigationActions, StackActions } from 'react-navigation';
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName: 'MainActivity' })],
});
this.props.navigation.dispatch(resetAction);
Here is how I do it:这是我如何做到的:
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
.重要的部分是
key: null
。
That wipes the stack while navigating from a child navigator to a parent navigator.这会在从子导航器导航到父导航器时擦除堆栈。
Do that if you get this error:如果出现此错误,请执行以下操作:
For animations, I use对于动画,我使用
// https://github.com/oblador/react-native-animatable
import * as Animatable from 'react-native-animatable'
I just control all the animations myself.我只是自己控制所有的动画。 Put them on any component you want by wrapping it with
<Animatable.View>
.通过用
<Animatable.View>
包裹它们,将它们放在您想要的任何组件上。
I found this way to go while using @react-navigation
Bashirpour's Answer .我在使用
@react-navigation
Bashirpour's Answer时发现了这种方法。 However, while trying out Functional components where you already have navigation in props
here is a neat way to write reset Stack action:但是,在尝试在
props
已经有导航的功能组件时,这里是一种编写重置堆栈操作的巧妙方法:
props.navigation.reset({
index: 0,
routes: [{ name: 'Dashboard' }]
})
For newest versions of react-navigation you should use StackActions for reset the stack, here's a piece of code:对于最新版本的 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...' },
}),
],
}))
}
To use Back, you need to find the unique key associated with the path.要使用 Back,您需要找到与路径关联的唯一键。 Inside your navigation reducer, you can search the existing state to find the first route on the stack using that path, grab its key & pass that to Back.
在您的导航减速器中,您可以搜索现有状态以使用该路径查找堆栈中的第一条路线,获取其密钥并将其传递给 Back。 Back will then navigate to the screen prior to the path you gave.
然后返回将导航到您提供的路径之前的屏幕。
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 );
You can use StackActions.replace
in this version您可以在此版本中使用
StackActions.replace
import { StackActions } from '@react-navigation/native';
navigation.dispatch(
StackActions.replace('Home', { test: 'Test Params' })
)
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>
);
}
NavigationActions.reset()
seems to be the preferable solution. NavigationActions.reset()
似乎是更好的解决方案。 One issue I ran into with it actions was the tab buttons.我在操作中遇到的一个问题是选项卡按钮。 Tabs would still show even if I explicitly turned them off in component.
即使我在组件中明确关闭了选项卡,它们仍会显示。 If I used navigation.navigate() instead of doing this via
reset()
it would work fine.如果我使用 navigation.navigate() 而不是通过
reset()
这样做,它会工作正常。
SomeComponentScreen.navigationOptions = {
header: null
};
A workaround for this annoyance that worked for me is to consecutively call multiple navigate
statements.对我有用的这种烦恼的解决方法是连续调用多个
navigate
语句。
navigation.goBack(); // this would pop current item in stack
navigation.navigate({
routeName: 'SomeOtherComponent'
});
The Answer is createSwitchNavigator , it those not stack up your navigation.答案是createSwitchNavigator ,它不会叠加您的导航。 Add your auth screen/navigator in a createSwitchNavigator with the home screen/stack.
将您的身份验证屏幕/导航器添加到带有主屏幕/堆栈的 createSwitchNavigator 中。
With that, when you navigate from home to log in, the stacks are not kept.这样,当您从家中导航以登录时,不会保留堆栈。
For more on it https://reactnavigation.org/docs/en/auth-flow.htmlLoginStack有关更多信息https://reactnavigation.org/docs/en/auth-flow.htmlLoginStack
The pop action takes you back to a previous screen in the stack.弹出操作将您带回到堆栈中的前一个屏幕。 The n param allows you to specify how many screens to pop back by.
n 参数允许您指定弹出的屏幕数量。
n - number - The number of screens to pop back by. n - number - 弹回的屏幕数量。
import { StackActions } from 'react-navigation';从“反应导航”导入 { StackActions };
const popAction = StackActions.pop({ n: 1, }); const popAction = StackActions.pop({ n: 1, });
this.props.navigation.dispatch(popAction); this.props.navigation.dispatch(popAction);
Just mix the two solutions given above and this will work just fine, basically we have to use StackActions and key: null.只需混合上面给出的两个解决方案,这将工作得很好,基本上我们必须使用 StackActions 和 key: null。 Without using StackActions, it was throwing some error
不使用 StackActions,它抛出了一些错误
import { NavigationActions, StackActions } from 'react-navigation';
const resetHandler = () => {
props.navigation.dispatch(StackActions.reset({
index: 0,
key: null,
actions: [NavigationActions.navigate({ routeName: 'PatientDetails' })]
}))
};
This works fine as of now:到目前为止,这工作正常:
import { NavigationActions, StackActions } from 'react-navigation'
resetStack = () => {
const navigateAction = NavigationActions.navigate({
routeName: 'Home',
params: {},
action: NavigationActions.navigate({ routeName: 'Home' }),
});
props.navigation.dispatch(navigateAction);
}
Found here in the docs: https://reactnavigation.org/docs/en/navigation-actions.html#reset在文档中找到: https : //reactnavigation.org/docs/en/navigation-actions.html#reset
In your StackNavigator and DrawerNavigator you have used Home as a key, and i think it has to be unique and that's why its creating the problem.在您的 StackNavigator 和 DrawerNavigator 中,您使用 Home 作为键,我认为它必须是独一无二的,这就是它产生问题的原因。 Can you please try replacing Home with Stack inside your DrawerNavigator.
您能否尝试用 DrawerNavigator 中的 Stack 替换 Home。
Hope this will help :)希望这会有所帮助:)
You can use popToTop()
action to reset your stack.您可以使用
popToTop()
操作来重置您的堆栈。 example:例子:
import { StackActions } from '@react-navigation/native';
navigation.dispatch(StackActions.popToTop());
React-Navigation Docs: https://reactnavigation.org/docs/stack-actions/#poptotop反应导航文档: https ://reactnavigation.org/docs/stack-actions/#poptotop
This fixed the issue for me ( React Navigation 5.x )这为我解决了这个问题( React Navigation 5.x )
import {NavigationActions} from 'react-navigation';
navigation.reset(
[NavigationActions.navigate({routeName: 'Profile'})],
0,
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.