-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to navigate from nested StackNavigator to parent's router screen? #335
Comments
First off, I'm having the same questions but here's an idea what you could try:
The docs include an example I think. Specifically:
So you would call something like:
As to your first problem:
have you tried passing down the navigation prop from the root |
Thanks @nico1510 I had already tried that before creating this issue, but today I managed to make it work. I still have some issues related to the CustomTabNavigator navigationOptions, as I'm passing a TabsNavigator and want to keep the top navbar dynamically linked to the tabs pages |
@goncalomarques How did you make it work? I've exactly the same problem. |
@zoontek I created wrapper components that I use in the screen property for a route I set. In these wrapper components, I pass down the
To use I don't think this is the optimal solution, just a quick fix. |
I had this issue and found that the ideal way to navigate between nested navigators is via the
|
This works totally fine if you want to go back from a nested navigator: navigation.dispatch({ type: 'Navigation/BACK' }) Edit this works when on the first page of the nested navigator, so not a complete solution.. |
I think I've bumped into the same issue as you. The about
|
Just a heads up for @goncalomarques answer: You can inline the nested navigator instead of making it a class: const AppNavigator = StackNavigator({
Home: { screen: HomeComponent },
Nested: { screen: ({ navigation }) => <DashboardNavigator screenProps={{ rootNavigation: navigation }} /> }
}); And the right call to navigate is: |
@Kerumen When using your example and dispatching a Example navigators:
Example dispatch action from header of one of the nested navigator's child components:
The resulting screen displayed is nested->screenOne, not nested->screenTwo as expected. If This results in the correct transition (but lacks parentNavigation prop in nested's children):
I tried another approach where I passed
Any thoughts on what I might be missing that will pass the sub-action through properly? |
@kylecrouse I stumbled upon the same problem.. const AppNavigator = StackNavigator({
Nested: { screen: DashboardNavigator }
}); |
Hmmm. I've got a bit of a catch-22 here it seems. @goncalomarques -- your solution (and @kylecrouse's) works for me as far as the navigation is concerned but I'm finding that when I do the initial dispatch to navigate to the nested TabNavigator and it's target screen, the params are getting squashed or not passed on. It's super frustrating. I think I can get around it by using redux instead of the params, but it's a bit of a hassle for such a small amount of data (one string). The good news is that calling dispatch() with a reset action on the outer navigation does pop everything back to where I want it. I'm concerned about other side effects too, but this gives me a little hope. UPDATE: using redux worked fine in my case to get the data to the screen in the nested tab navigator. I'm not sure what other side effects I'll run into on the other screens, but at least I have that working for now. |
I have also spent hours on this problem, thank you with the idea of using wrapper components. I have found the following fix using Redux.
I hope it is useful. |
I have a similar problem with Presentational/Container ocmponents and navigating. |
Is it possible to nest just stacknavigator? |
Sorry one question... nesting my Navigation is a good solution for now (later I will use Redux-Style), but now the
|
Solutions by @goncalomarques @Kerumen work well for passing Anyone looking here for a way to pass rooNavigationState might benefit from the following way -
With this way, the nested screen navigators(screenNavigator1 and screenNavigator2) would now receive a prop that has the navigation state of the root navigator. |
@ramirobg94 how do you do to set the initialState of the reducer ? |
https://reactnavigation.org/docs/navigators/navigation-prop#dispatch-Send-an-action-to-the-router able to navigate from child to parent. for example from teams screen to loading. have not tried parent to child. |
@goncalomarques Shouldn't |
@goncalomarques I'm in the same situation like you. One wrapper for |
Hi! In an effort to get the hundreds of issues on this repo under control I'm closing issues tagged as questions. Please don't take this personally - it's simply something we need to do to get the issues to a manageable point. If you still have a question I encourage you to re-read the docs, ask on StackOverflow, or ask on the #react-navigation Reactiflux channel. Thank you! |
@goncalomarques I was just about to kill myself. thanks your solution worked. |
@Kerumen but when you reverted your code to have sub-actions working again, the rootNavigation is not passed down anymore and thus the problem of this question is not fixed.. How did you go about that then? |
@Kerumen this line is not working for me in the nested navigator - this.props.screenProps.rootNavigation.navigate('Home') I managed to get the call working only when calling the screenProps directly, without a preceding this.props: screenProps.rootNavigation Could anyone please explain why it only works this way? I haven't defined a new component though, this is how I passed through the rootNavigator:
and then in render(): |
@goncalomarques - How do I pass extra props to NestedNavigatorWrapper? besides root navigation I need to pass extra data to DashboardNavigator from AppNavigator Please help |
@uri3000 <SignupWizard screenProps={{ rootNavigation: this.props.navigation }} /> |
we're going to add an escape hatch for this with |
My Solution to resolve all accessing problems:
|
@peni4142 I would like to know how to use this. Could you give more information? |
The solutions above are overly complicated! If you are using Redux, you can store a reference with a middleware and use it anywhere, no matter the nesting... STEP 1: create a redux storeRef middleware
STEP 2: add the middleware to your redux store
STEP 3: create the action
STEP 4: there is no step 4, you are done!Usage:
|
This method works but because it's not dispatched from within a In order to address the issue of removing the Navigator from the Stack using
|
If you want to
|
I found an easy solution example : https://stackoverflow.com/a/51333660/2849146 for more details : https://reactnavigation.org/docs/en/connecting-navigation-prop.html |
Navigating without the navigation prop。also can resolve this question。 Calling functions such as navigate or popToTop on the navigation prop is not the only way to navigate around your app. As an alternative, you can dispatch navigation actions on your top-level navigator, provided you aren't passing your own navigation prop as you would with a redux integration. The presented approach is useful in situations when you want to trigger a navigation action from places where you do not have access to the navigation prop, or if you're looking for an alternative to using the navigation prop. You can get access to a navigator through a ref and pass it to the NavigationService which we will later use to navigate. Use this only with the top-level (root) navigator of your app. // App.js
import NavigationService from './NavigationService';
const TopLevelNavigator = createStackNavigator({ /* ... */ })
class App extends React.Component {
// ...
render() {
return (
<TopLevelNavigator
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
);
}
} In the next step, we define NavigationService which is a simple module with functions that dispatch user-defined navigation actions. // NavigationService.js
import { NavigationActions } from 'react-navigation';
let _navigator;
function setTopLevelNavigator(navigatorRef) {
_navigator = navigatorRef;
}
function navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
}
// add other navigation functions that you need and export them
export default {
navigate,
setTopLevelNavigator,
}; Then, in any of your javascript modules, just import the NavigationService and call functions which you exported from it. You may use this approach outside of your React components and, in fact, it works just as well when used from within them. // any js module
import NavigationService from 'path-to-NavigationService.js';
// ...
NavigationService.navigate('ChatScreen', { userName: 'Lucy' }); In NavigationService, you can create your own navigation actions, or compose multiple navigation actions into one, and then easily reuse them throughout your application. When writing tests, you may mock the navigation functions, and make assertions on whether the correct functions are called, with the correct parameters. |
This looked perfect, but it doesnt work inside a switch navigator. Any ideas for that? :/ |
just in your onPress method
This will clear your route history navigate to your desired route and when you press back it will redirect to initial screen of the tab :) |
@n0umankhan thanks for your example, added from my custom |
The best and only one working alternative for v3.* |
While the issue navigating back from nested navigators is fixed #5588, I added a workaround as you can see here https://github.com/proyecto26/react-native-modular/blob/master/src/services/Navigation/index.js#L218 It's required to use a "service" in order to register the history of the routes and compare after navigating to remove the initial route of the nested navigators :) |
2 or 3 days of pain with the navigation finding a solution for the undefined "this.props.navigation" ! When you use redux + nested navigation (switch navigation with 2 or more stack navigation) from single screen (login / register) to tab navigation... and you call the Main screen from App.js like this:
Not sure the base of the problem, but all of this stuff leads to the problem where I can't have access to store navigation inside MainScreen, but, I can call navigation inside the AuthLoadingScreen middleware (or TabNavigation...) for example. So inside the MainScreen, I've putted the @microcipcip reducer solution - This will help me to reach the navigation where I can't (and trigger for example the logout function). |
For those of you that just can't handle the bullshit anymore: Main/Root/App.js:
Anywhere:
|
THANK YOU !!!! i got your code to work pushing a button in a component in a stack navigator nested inside a switch navigator that makes the switch navigator change its current route. however .... if i put this:
inside of a component's
any idea how i can run your code automatically upon instantiation of the app ? |
Looks like an import error. Did you correctly import |
silly me _ thanks ! got it working but also had to switch to using this instead :
YOU ROCK !!!! 😺 |
Thanks for solution, it helps and save my time |
@iuliuvisovan this doesn't work for tab navigator |
you can do something like this |
Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro. |
I have several nested navigators with the following structure:
How can I navigate from
ScreenOneDetails
toHome
?Already tried to dispatch it as an action:
But all I get is an error -
There is no route defined for key splash. Must be one of: 'ScreenOneDetails','ScreenOneSettings'
I know that this makes sense, as the
navigation
prop that is passed toScreenOneDetails
is the one created by theScreenOne
StackNavigator. However, is there any way to access thenavigation
prop created by parent navigators? And how would I go the other way around, e.g: fromLogin
toScreenOneSettings
?The text was updated successfully, but these errors were encountered: