Comments (14)
I need to pass same "userId" param to all Tabs inside Tab.Navigator
Doc says there is no "dangerouslyGetParent().getParams" in React Navigation 5 any more.
However it is totally unclear how to share/access same "nav-param" for all Tabs inside TabNavigator now.
One solution is using external storage (react-context/redux/other).
I found following solution/workaround. Hope it helps somebody.
<Stack.Screen name="Settings" >
{ (props) => (
<Tab.Navigator>
<Tab.Screen name="Tab1" component={ Tab1 }
initialParams={ props.route.params } // <- pass params from root navigator
/>
<Tab.Screen name="Tab2" component={ Tab2 }
initialParams={ props.route.params }
/>
</Tab.Navigator>
)}
</Stack.Screen>
Navigation params pass from root stack-navigator to all Tabs
from rfcs.
this causes a lot of confusion - react-navigation/react-navigation#4811
we should document this.props.navigation.dangerouslyGetParent().getParam(...)
as a way to get the params from the parent, or provide a method that gets params from the parent without the word dangerously
maybe...
from rfcs.
I don't think the getParentParam
is necessary, because if we passed params to child navigator, we can reference the params by dangerouslyGetParent().getParams
in the child screen, and we also can wrap the navigator to decide how to use the params for all the child screen (see pull request below).
But at first we should let the child navigator to receive params. There is some issue in current version and I have made a pull request #4306 .
from rfcs.
I have a use case where It would be helpful to me that any screen / navigator under a certain navigator gets a common param, and I really believed this would be the default behavior (passing down all params with the child always having priority when param names conflict).
I will use a workaround by extending navigator and using react context in the meantime 😄
from rfcs.
Using react context wrapping my navigator is exactly what I did, sorry I did not give more details in my above message 😄. And once hooks land in stable react-native it'll get even cleaner to use.
from rfcs.
Since it is react
-navigation
I guess params should be converted to props. It should be passed to a target component only. All further props-params manipulations in the component is up to a developer.
Since I believe the navigator should be able to made as a HOC (without any scene changed inside itself), params should be available to be taken in navigationOptions
, for example, for a header configuration.
from rfcs.
@mtnt - they are props. this.props.navigation.state.params
. that's not really what this issue is about though. the question here is how we should deal with params when they are passed into a navigator, so if you navigate to a screen that is just a react component vs a screen that is a navigator, would params be passed through to the screen rendered by the navigator or not?
from rfcs.
@brentvatne I meant first level props - this.props.param0
, but ok, I`ll open another one issue for this point.
About your comment. As I already said, I think params should be passed into a navigation target screen only (without passing through). What to do with it further is the screen responsibility.
from rfcs.
Hi @Titozzz
If you need to build some kind of multiscreen stateful wizzard you can share state across those screens by wrapping the navigator.
MyStatelessStackNavigator = createStackNavigator({})
// Forward the prop
MyStatefulStackNavigator = ({navigation}) => (
<MyStateProvider>
<SomeFancyWizzardStepHeader/>
<MyStatelessStackNavigator navigation={navigation}/>
</MyStateProvider>
);
// Very important otherwise MyStatefulStackNavigator is not considered as a navigator
MyStatefulStackNavigator.router = MyStatelessStackNavigator.router;
export default MyStatefulStackNavigator;
This is a common pattern where you just wrap a navigator inside custom one to enhance it.
More infos here: https://reactnavigation.org/docs/en/custom-navigators.html
Unlike global state based solutions, this one will actually reset its state when you navigate away from this navigator, which makes it more suitable for transcient state like multi-screen forms/wizzards... I think we should do a better job at documenting this kind of patterns with react-navigation. Will probably write a blog about it soon.
Note you might be tempted to try to use "screenProps" here but actually this should only be used on root app container, and after discussing with Satya last year he suggested using context is the way to go for this kind of usecase, and maybe screenProps would be deprecated some day.
Note if you are looking for an easy to use state provider to make your stack navigation stateful, I think unstated is a very decent option and anyone knowing React will understand how to build features with this very easily. Once it's setup you almost get no learning curve. Only difference is setState being async (which imho is a nice addition).
And if you don't need a stateful wrapper, you can still use the trick above and add a simple React context to propagate a static value to all subscreens.
from rfcs.
I was struggling with the same, and after almost a week of frustration finally used context and got what I wanted, demonstrated in react-navigation/react-navigation#5646
I think the mention of possibilities with the use of cotext api (though it is in parent platform i.e. react) in react-navigation documentation would help a lot.
Should we / I open an issue for this on documentation site repo?
from rfcs.
@bhave-abhay - a docs page for that could be really great! you would probably be a great person to write it given the experience you've had, can you open a pr for it?
from rfcs.
@brentvatne
Let's assume a routing like below:
DrawerNavigator:
|______ StackNavigator
|______ Screen 1
|______ TabNavigator
|_______ Tab 1 <--- initial route
|_______ Tab 2
|_______ Tab 3
One scenario for the routing is an app that shows a list of items in Screen 1
and shows an item's detail when the user pressed on the item. because of the massive amount of information, the developer decides to show the information in three tabs (price tab, technical info, and contact tab), So the tabs are related, also, assume that the developer should fetch the data by sending 3 different requests to a server (in the scenario I'm thinking about the tabs are able to work completely separated from each other, in other words, although the tabs are showing information of the same Item all of their processes are isolated from each other). in the other hand, the server may expect an ItemId and some other parameters in the request for each tab.
in the current implementation, we should pass all parameters to the TabNavigator
and extract the required params in each tab using this.props.navigation.state.params
in Tab 1
and this.props.navigation.dangerouslyGetParent().getParams
in the other Tabs. it has two cons in my opinion:
- If the developer wants to change the order of the tabs, he/she must change the code to retrieve params, because of two different access way to the parameters.
- Developers like me may like to convert params to component props to easily accessible in a consistent way (by using something like below)
Tab 1: {
screen: (props) => (<ScreenWrapper component={ItemOverviewScreen} params={props}/>)
}
Class ScreenWrapper {
public render() {
const Component = this.props.component;
return (
<Component {...this.props.params}/>
);
}
}
Class ItemOverviewScreen {
// work with props without any concern and knowledge about routings parameter passing
}
Not passing down the params causes we lose the above ability in tab navigators at least.
- For some reason, Let assume that the app's routing is changed like below:
DrawerNavigator:
|______ StackNavigator
|______ Screen 1
|______ TabNavigator
|_______ Tab 1 <--- initial route
|_______ Tab 2
|_______ Tab 3
|______ Tab 3 <--- the same screen used in above Tab 3
the developer must check both this.props.navigation.state.params
and this.props.navigation.dangerouslyGetParent().getParams
to cover both routing in one place.
My suggestion
Passing the params
of each tab by wrapping them into an object with a key of the corresponding Tab routing name. I mean something like below:
The developer doing navigate to Tab Navigator:
NavigationAction.navigate ({
routeName: TabNavigator,
params: {
Tab 1: {
// params of Tab 1
},
Tab 2: {
// params of Tab 2
},
Tab 3: {
// params of Tab 3
},
}
});
the library should pass only the corresponding params to each Tab in the screen: (props) => ....
probably we can extend the suggestion for other Navigators include nested ones.
from rfcs.
@brentvatne getParam is undefined
from rfcs.
I need to pass same "userId" param to all Tabs inside Tab.Navigator
Doc says there is no "dangerouslyGetParent().getParams" in React Navigation 5 any more.
However it is totally unclear how to share/access same "nav-param" for all Tabs inside TabNavigator now.
One solution is using external storage (react-context/redux/other).I found following solution/workaround. Hope it helps somebody.
<Stack.Screen name="Settings" > { (props) => ( <Tab.Navigator> <Tab.Screen name="Tab1" component={ Tab1 } initialParams={ props.route.params } // <- pass params from root navigator /> <Tab.Screen name="Tab2" component={ Tab2 } initialParams={ props.route.params } /> </Tab.Navigator> )} </Stack.Screen>
Navigation params pass from root stack-navigator to all Tabs
thank you so much for this. I was trying to solve this problem from last 2 days luckily i reached here
from rfcs.
Related Issues (20)
- Action property that indicates to routes that they should not change index HOT 1
- Improve ergonomics of back HOT 1
- Navigator config to pass params down HOT 1
- Add unsetParams to navigation prop HOT 2
- Reset state action HOT 2
- Expose logic for initializing state of createAppContainer HOT 4
- On will/didFocus subscribe, stop firing the listener if current screen is focused HOT 2
- Idea: Preloading HOT 6
- <StaticNavigator> for tests/storybook HOT 14
- StackActions.popToRouteName(routeName) HOT 2
- Alternative API for defining navigators HOT 12
- how to send navigation events between peer navigators? HOT 4
- Deep linking with authentication
- How to hide tab bar item n react-navigation HOT 3
- Ability to show screens on top of native modals
- useNavigationParams hook HOT 1
- Add useMaterialTabsHeight HOT 1
- Typesafe Stack & Navigation HOT 1
- devTools prop HOT 5
- [RFC] TabView API change
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rfcs.