react-navigation / react-navigation Goto Github PK
View Code? Open in Web Editor NEWRouting and navigation for your React Native apps
Home Page: https://reactnavigation.org
Routing and navigation for your React Native apps
Home Page: https://reactnavigation.org
Hey, thanks for the release! I have a screen in my app that has some content that takes up about a third of the top of the screen, and below that I want to have a nested tab view with the tab bar just below the other content at the top. With ex-navigation it was simple to render the <SlidingTabNavigation>
component below the rest of my component contents, but I can't figure it out with this library. It seems as I define my nested navigators as screens in a parent navigator, I don't know where I would even define that other content? Do I need to write a custom navigator?
Thanks for the help!
Hi,
I'd like to ask for an example of invoking .navigate from with the left or right elements of a header. Something along the line of
header: ({ state, setParams }) => {
// The navigation prop has functions like setParams, goBack, and navigate.
let right = (
<Button
title="Options"
onPress={() => this.props.navigation.navigate('Options')}
/>
);
return { right };
},
where Options is another screen. The above doesn't work. I'm missing how to get hold of the navigation object.
Thanks
Can we get access to the global dispatch/nagivate/etc functions, so that we don't have to pass them through our component trees?
Hi all, I am trying to setup navigation in my app but having some trouble navigating from nested views. Im pretty sure im doing this wrong since I cant go from a 2nd level view to another 2nd level view in another Navigator.
Basically I want to go from LoginView to MainView somehow but keeping WelcomeNavigator separate from HomeNavigator (mostly for organization purposes but also to clear the stack when transitioning from !isLoggedIn screen to isLoggedIn screen)
Can someone point me in the right direction? Thanks!
const WelcomeNavigator = StackNavigator({
Login: { screen: LoginView},
Register: { screen: RegisterView}
}, {
headerMode: 'none'
});
const HomeNavigator = TabNavigator({
Main: {screen: MainView },
Settings: { screen: SettingsView}
});
const MasterNavigator = StackNavigator({
Welcome: { screen: WelcomeNavigator },
Home: { screen: HomeNavigator }
},
{
headerMode: 'none'
});
Question: Does it already run with 'normal' React.js on desktop/browser apps, made with Meteor or Electron, based on Chromium, V8 etc.? Are there any info resources?
It would be nice if we could optionally (or by default) render the drawer on top of the header rather than underneath it if the DrawerNavigator
is nested. Let's say I have the following routes:
const MainNavigator: any = DrawerNavigator({
Dashboard: { screen: Scenes.Dashboard },
Log: { screen: Scenes.Log },
}, {
initialRouteName: 'Dashboard',
});
const AppNavigator: any = StackNavigator({
Main: { screen: MainNavigator },
Login: { screen: Scenes.Login },
Password: { screen: Scenes.Password },
}, {
initialRouteName: loggedIn ? 'Main' : 'Login',
});
Currently, the problem is if you are on the Dashboard screen, the drawer opens up underneath the header. It's acceptable for most routes, but I have some screens that render a transparent header and it looks odd when the drawer renders underneath it.
Thanks!
Useful for custom back button, hamburger menu, etc.
static navigationOptions = {
header: {
left: React.Element<*>
}
}
As Martin suggested in old repo, it would be great to have an ability to define a custom style for a header on a Navigator level.
This is already getting implemented in #1. As a follow-up, we will expose style.
It's currently like this,
static navigationOptions = {
drawer: {
icon: ({ route, focused, tintColor }) => React.Element<*>
}
}
Change it to
static navigationOptions = {
header: ({ state, focused, tintColor }) => ({
icon: React.Element<*>
})
}
In Expo we use a translucent StatusBar by default on Android, and some normal React Native projects may do this as well because it makes it easier to reason about cross-platform since the iOS StatusBar is always translucent.
We may need to upstream a constant to React Native that we can use to check if the StatusBar is translucent, and then add any necessary paddingTop to the navigation bar when it is.
Thanks for the awesome work on this library!
I'd like to use the classical header with a hamburger pattern in combination with the DrawerNavigator but I can't figure out how to do so apart from manually including the header in every screen where I want it rendered, which seems a bit redundant. Is that actually how I should do it or is there a better way?
An example including a header would be much appreciated. Examples of StackNavigator nested behind DrawerNavigator would be nice too.
Hello there,
first of all thank you for creating react-navigation, let's hope it become the standard for the react-native navigation.
I'm trying to migrate to react-navigation an application (that was previously using ex-navigation) and I'm having some issues.
The app navigation follows a common flow: There is an authentication screen, if the user is authenticated he can access the "core" of the app, where there is a DrawerNavigator
and where each drawer route is a StackNavigator
.
I tried to implement the app this way (feel free to tell my I'm dumb if i'm wrong):
1. The first stack
The first screen is a splash screen, it initializes the app and (almost instantly) redirect the user to an authentication screen or to the main screen.
I handled this with a StackNavigator:
const AppStackNavigator = StackNavigator({
SplashScreen: { screen: SplashScreen },
AuthScreen: { screen: AuthScreen }, // User not logged in
MainDrawerNavigator: { screen: MainDrawerNavigator } // User logged in
}, {
headerMode: 'screen'
})
In SplashScreen
I'll do some stuff and then redirect the user to AuthScreen
or to MainDrawerNavigator
by resetting the stack (this is the only way to reset the stack at the moment, am I right?):
this.props.navigation.dispatch({
type: 'Reset',
index: 0,
actions: [{ type: 'Navigate', routeName: 'MainDrawerNavigator' }]
})
2. The drawer navigator
If the user is authenticated he can access MainDrawerNavigator
, which contains the "core" of the application, and navigate through all the app using the drawer. Each drawer link is a stack navigator.
const MainDrawerNavigator = DrawerNavigator({
ApplianceStackNavigator: { screen: ApplianceStackNavigator },
SettingStackNavigator: { screen SettingStackNavigator }
}, {
initialRouteName: 'ApplianceStackNavigator',
headerMode: 'screen'
})
3. The stack navigator sub-routes
const ApplianceStackNavigator = StackNavigator({
ApplianceListScreen: { screen: ApplianceListScreen },
NewApplianceScreen: { screen: NewApplianceScreen }
}, {
initialRouteName: 'ApplianceListScreen',
headerMode: 'screen'
})
And here is where the issue arises.
When I'm inside one of the drawers sub-routes (Appliance/Setting) the navigation doesn't work correctly.
For example, if I'm in the the ApplianceListScreen
and I want to go to the NewApplianceScreen
using this.props.navigation.navigate('NewApplianceScreen')
I'm expecting that the route gets pushed, but instead the stack is reset (resetted?) to it.
TLDR: Using a StackNavigator
as a DrawerNavigator
route doesn't seems to work correctly: the routes don't get pushed correctly.
I know that this lib is super-young, and that my issue description might be a bit of a mess, but thank you in advance anyway :)
P.S.: I wanted to create a repo to show the problem but I discovered this issue while working on a work-related-project and publishing the repo would mean re-writing all the code because I'm on NDA (still, I can setup a dummy repo in the next days if it is needed).
P.P.S: The entire app entry point is the following:
const ApplianceStackNavigator = StackNavigator({
ApplianceListScreen: { screen: ApplianceListScreen },
NewApplianceScreen: { screen: NewApplianceScreen }
}, {
initialRouteName: 'ApplianceListScreen',
headerMode: 'screen'
})
const MainDrawerNavigator = DrawerNavigator({
ApplianceStackNavigator: { screen: ApplianceStackNavigator }
}, {
initialRouteName: 'ApplianceStackNavigator',
headerMode: 'screen'
})
const AppStackNavigator = StackNavigator({
SplashScreen: { screen: SplashScreen },
AuthScreen: { screen: AuthScreen },
MainDrawerNavigator: { screen: MainDrawerNavigator }
}, {
headerMode: 'screen'
})
export default class SlowdiveLoveReact extends Component<void, void, void> {
render () {
return (
<View style={styles.container}>
<Provider store={store}>
<AppStackNavigator />
</Provider>
</View>
)
}
}
Can't find any api for this purpose. Something like in react-native-navigator:
{
navBarTextColor: '#000000', // change the text color of the title (remembered across pushes)
navBarBackgroundColor: '#f7f7f7', // change the background color of the nav bar (remembered across pushes)
navBarButtonColor: '#007aff', // change the button colors of the nav bar (eg. the back button) (remembered across pushes)
navBarHidden: false, // make the nav bar hidden
navBarHideOnScroll: false, // make the nav bar hidden only after the user starts to scroll
navBarTranslucent: false, // make the nav bar semi-translucent, works best with drawUnderNavBar:true
navBarTransparent: false, // make the nav bar transparent, works best with drawUnderNavBar:true,
topBarElevationShadowEnabled: false, // Android only, default: true. Disables TopBar elevation shadow on Lolipop and above
navBarNoBorder: false, // hide the navigation bar bottom border (hair line). Default false
drawUnderNavBar: false, // draw the screen content under the nav bar, works best with navBarTranslucent:true
}
There should be a hosted demo of https://github.com/react-community/react-navigation/blob/master/website/, linked to both from the docs and the GH repo
Hi,
This package seems pretty good. Bravo for the release.
I've seen in the Facebook Roadmap that they will release a new navigation package (here is a screenshot) :
(source: https://github.com/facebook/react-native/wiki/Roadmap)
Why should I use this package and not the future Facebook "official" one?
Cmd-click on the website is broken
Before being prod-ready, we need to make sure a11y features work well on both platforms.
assume we have this component.
how can i trigger navigate event from the top level of App
component?
in this example lets say under someEvent
function.
this event is for top level (like new push notification arrived) and not per each individual loaded screen so it has to happen in App
class.
const AppNavigator = StackNavigator(SomeAppRouteConfigs);
class App extends React.Component {
someEvent() {
// call navigate for AppNavigator here?
}
render() {
return (
<AppNavigator />
);
}
}
Currently it's supported only with headerMode: screen
. We should support it on float
also and hide the header with animation.
Got the following output on
'npm install' within the react-navigation folder...
'rm' is not recognized as an internal or external command. [...]
Win 7
npm v 4.1.2
node v 6.9.4
PS:
Tried to hint this issue with rimraf in package.json, but then the install breaks at
cannot read property split of undefined at compile-docs.js.
I'm wondering seeing so much 'Mac-first approaches' in React land.
Shouldn't traditional MS Windows dev-environments supported from the beginning?
I use TabNavigator and here's the full code:
class HomeScreen extends React.Component {
render() {
return <View style={{flexDirection:'row', backgroundColor: 'red', height: 300,
justifyContent:'flex-end', paddingTop: 30}}>
<Text>Hello, Navigation!</Text>
</View>
}
}
class SecondScreen extends React.Component {
render() {
return <View style={{flexDirection:'row', justifyContent:'flex-end', paddingTop: 30}}>
<Text>Hello, Second!</Text>
</View>
}
}
const AppContainer = TabNavigator({
HomePage: {screen: HomeScreen},
SecondPage: {screen: SecondScreen}
}
)
As you can see, when app initially launches, the text "flies" in ... How can I disable this effect?
Thanks in advance!
How can we add icon (or image) buttons in the navigation bar ?
Thanks
Gilles
Is this on the roadmap??
Main: {
screen: MainScreen,
navigationOptions: {
header: {
left: <Button title="Back" />,
},
},
}
Nothing shows when I try to display an element on the left side of the header (but it does with right
). Could this not be supported yet by any chance?
First thanks guys for this library!
It's super easy to understand unlike others navigation libraries.
Screen (component) can change its state or props can be changed.
I tried to setParams in componentWillUpdate and other lifecycle methods and then change "right" and "title" in navigationOptions but it invoked only one time.
Sorry if I asked a dumb question.
Thanks in advance.
Each screen should be able to set properties on the device's status bar, and the container defined in createNavigationContainer
should get the options on state change, and apply them natively.
From the code, there are a bunch of places where prop types are used, but not indicated in other places.
HeaderComponent
to CardStack
but CardStack doesn't seem to do anything with itHi,
I have an issue trying to open a detail screen.
In my routing config, I have this:
const Navigator = DrawerNavigator({
Details: {
path: 'details/:pk',
screen: DetailsContainer
}
[...]
});
In some Component, I navigate like this:
navigation.navigate('Details', {pk: 1})
In the Detail Component, I don't have navigation.state
:
console.log(navigation)
=> {key: "Details", routeName: "Details"}
Any idea what I'm doing wrong?
I think this would will be useful for changing the background color of a screen
When using with Redux we have to manually create the objects to dispatch:
dispatch({ type: 'Navigate', routeName: 'Home' });
This make us dependent on the type
string value key.
I took a look the source code and found that addNavigationHelpers.js
have the so called Action creators.
It might me helpful to move those functions to a separate file and include them on addNavigationHelpers.js
but also expose them to be imported on custom reducers.
export const navigate = (routeName, params, action) => ({
type: 'Navigate',
routeName,
params,
action,
});
// ...
Posible usage on custom reducers:
import * as actions from 'react-navigation/actions';
function reducer(state = initialState, action) {
switch (action.type) {
case LOGIN_SUCCESS:
return AppNavigator.router.getStateForAction(actions.navigate('Home'), state);
default:
return AppNavigator.router.getStateForAction(action, state);
}
}
Hello,
I'm trying to set up a TabNavigator inside a StackedNavigator, sort of like this:
TabsNavigator = TabNavigator({
HomeScreen: {
screen: HomeScreen,
navigationOptions: {
tabBar: () => ({
label: 'Home'
})
}
},
MyAction: {
screen: Settings,
navigationOptions: {
tabBar: () => ({
label: 'Settings'
})
}
},
}, {
tabBarPosition: 'bottom',
animationEnabled: true,
swipeEnabled: true
});
ModalNavigator = StackNavigator({
Home: {
screen: TabsNavigator
}
});
My issue is, since I'm using Redux, I can pass the outer StackedNavigator the nav state easily enough:
import { ModalNavigator } from '../scenes';
const AppNavigatorWithRedux = connect()(ModalNavigator);
<AppNavigatorWithRedux
navigation={navigation}
/>
But I don't know how to pass the TabNavigator's state down to it. I'm assuming right now I'm going to have to wrap it in another component and get my other navigation state, but is there another/simpler way?
My reducer is:
import { ModalNavigator, TabsNavigator } from '../scenes';
const navReducer = (state, action) => {
return {
ModalNavigator: ModalNavigator.router.getStateForAction(action, state),
TabNavigator: TabNavigator.router.getStateForAction(action, state)
};
};
const appReducer = combineReducers({
navReducer,
mainReducer
});
I get this error when i want render navigator
Here is my code
import { TabNavigator } from 'react-navigation';
import * as screens from 'AppScreens';
const configure = {};
for (const name in screens) {
if (!screens.hasOwnProperty(name)) {
continue;
}
configure[name] = {
screen: screens[name]
};
}
const options = {
tabBarOptions: {
activeTintColor: '#e91e63',
},
}
export const Navigator = TabNavigator(configure, options);
export const App = () => (
<Provider store={store}>
<Navigator />
</Provider>
);
In one of my Tabs i need to load Data from the server and do some heavy rendering. I would like to defer that until the Tab is focused in order to improve the JS-Thread performance. How should i implement that?
People will want to use images, custom fonts etc for the title. So we should allow react elements too
static navigationOptions = {
header: {
title: React.Element<*>
}
}
This should style a text and icon colors. See #30 for reference
New views or unique features
Often navigation needs are specific to certain apps. If your changes are unique to your app, you may want to fork the view or router that has changed. You can keep the source code in your app, or publish it on npm as a react-navigation compatible view or router.
This library is intended to include highly standard and generic navigation patterns. But it
It looks like the New views section is incomplete and just ends at the noted bolded section
Can we manually navigate to a deep link/URI, or should we use Linking.openURL(...)
?
Is there a plan to introduce the same component that is in ex-navigation for this purpose? Thanks a lot for this lib!
What I have in mind is that the android back button "just works" while it can be overridden like this i.e. not worrying about it but having the ability to control what happens when the back button on android is pressed, if needed.
use case: I need to select some items from a list, and on android, the back button takes me out of the "selection mode", similar to selecting mail in gmail app.
Tab examples of HelloHybrid
(SettingsView) and NavigationPlayground
(StacksInTabs / CustomTabs) are broken with following error:
This issues occurs using latest react-native-tab-view
v.0.0.53.
Downgrading to react-native-tab-view
v.0.0.52 does fix this issue.
I'm trying to reset the stack in a StackNavigation using:
dispatch({
type: 'Reset',
actions: [{
type: 'Navigate',
routeName: 'Home',
}],
})
However, this gives an error: "There should always be only one scene active, not 0".
If I try to dispatch() the reset action, followed by a navigate(), then it works but it does not "forget" any part of the history stack. How can I reset the stack?
First of all, congrats on the release. Everything looks great and is overall well documented.
One thing I think is missing are documented reasons why this would be a better option than using the built-in NavigationExperimental
library that is actively being developed on the react-native side.
For example, my team is using NavigationExperiemental
on the react-native side and react-router
on the web side. Is the primary gain by using this new react-navigation
library that you can share all navigation logic between both?
I'd be happy to issue a PR documenting this if I just had a better understanding. Thanks for your time.
Hi,
First, thank you for this module !
I have an issue when using a TabNavigator nested in a DrawerNavigator: tabs are not displayed.
This issue appears only when I go to the nested TabNavigator from the Drawer menu link and when using navigate('MyNestedTabStack')
like in the get started guide.
Here is an example:
class HomeScreen extends React.Component {
render() {
return <Button
onPress={() => this.props.navigation.navigate('Projects')}
title="Go to Projects"
/>;
}
}
class RecentProjectsScreen extends React.Component {
render() {
return <Text>List of recent projects</Text>
}
}
class AllProjectsScreen extends React.Component {
render() {
return <Text>List of all projects</Text>
}
}
const ProjectScreenNavigator = TabNavigator({
Recent: { screen: RecentProjectsScreen },
All: { screen: AllProjectsScreen },
});
const App = DrawerNavigator({
Home: { screen: HomeScreen },
Projects: { screen: ProjectScreenNavigator }
});
AppRegistry.registerComponent('App', () => App);
As far as I know we have to first init a clean RN project and then add react-navigation via yarn or npm to the new project.
If I got it right, we then have to navigate in the new project folder to node_modules/react_navigation and do the steps described here:
https://github.com/react-community/react-navigation/tree/master/examples/NavigationPlayground
cd react-navigation
npm install
cd examples/NavigationPlayground
npm install
cd ../..
react-native start
cd examples/NavigationPlayground
react-native run-ios # ignore packager starting error
react-native run-android # ignore packager starting error
But if I do this, I get: 'Android project not found' even with two separate shells.
How do we run the examples on the correct way?
Am I the only one?
I think for now we could create a WIP PR and start documenting this one. There were a few request already (i.e. #31) and we want to have that once we're out of beta release anyway.
@satya164 had a chance to make a migration on one of his projects (NavigationExperimental -> React Navigation): satya164/PocketGear@8322cbc
I think it would be great to have docs and maybe even codemods.
Currently the second argument received by a navigation options item is the previous config returned from a parent navigation options, and the options passed to getScreenConfig
.
IMO it's a confusing behaviour, because fundamentally they are different types of objects, one is the configuration for navigator, other is arbitrary options the navigator can pass to the configuration function. For example, the tab navigator can provide a focused
argument for the icon, which doesn't make sense in a config.
The way this works is, only the global navigator config receives the options passed to the getScreenConfig
, and it has to explicitly merge it with, say, header config and return it. Which means if you have a static header configuration for screens, and then add a header configuration at the global level to be used as default, it breaks the screen configuration because it doesn't receive the options anymore and you've to explicitly merge the options in the global navigator config. Same for the route navigation config, which will break if you add a screen config.
Personally I think the confusing behaviour and the learning curve associated with it is not worth getting rid of one extra function.
global config - the navigationOptions
passed in the second argument to the navigator
screen config - the static navigationOptions
in the screens
route config - the navigationOptions
specified for individual routes in the first argument to the navigator
Flow types for both,
type NavigationOptionItem<T> =
| T
| (navigation: NavigationScreenProp<*,*>, T) => T
type IconOptions = {
focused: boolean;
tintColor: boolean;
}
These are the current api and the proposals we discussed:
Options is the result of previous header function/previous header object
header: (navigation, options) => ({
...options,
icon: ({ focused, tintColor }) => <Icon name={'settings' + focused ? '' : '-outline'} color={tintColor} />
});
Flow type,
type HeaderOptionItem = NavigationOptionItem<{
title: string;
icon: IconOptions => React.Element<*>;
}>
How it is used,
const { icon } = router.getScreenConfig(...);
return icon({ focused, tintColor });
router.getScreenConfig
doesn't deal with options passed to icon, so it's pretty generic, navigators can do whatever they wantOptions is the result of previous header function/previous header object merged with params passed to getScreenConfig
header: (navigation, options) => ({
...options,
icon: <Icon name={'settings' + options.focused ? '' : '-outline'} color={options.tintColor} />
});
Flow type,
type HeaderOptionItemConfig = {
title: string;
icon: React.Element<*>;
}
// not sure if `HeaderOptionItemConfig & ?IconOptions` is valid, but wanted to denote that the merged object may or may not contain icon options even if the navigator always passes it
type HeaderOptionItem = NavigationOptionItem<HeaderOptionItemConfig & ?IconOptions>
How it is used,
return router.getScreenConfig(.., { focused, tintColor }).icon;
focused
doesn't make sense inside navigationOptions.header
. For some things like tintColor
, it could be irrelevant if tintColor
might make sense in the config, but see next one for thatgetScreenConfig
has to handle the options, limited to objects onlynavigationOptions
or the params passed to getScreenConfig
? Can I override the other?Options is the result of previous header function/previous header object
header: (navigation, options) => ({
...options,
activeTintColor: 'orange',
inactiveTintColor: 'blue',
activeIcon: <Icon name='settings' color='blue' />,
inactiveIcon: <Icon name='settings-outline' color='orange' />
});
Flow type,
type HeaderOptionItem = NavigationOptionItem<{
title: string;
activeTintColor: string;
inactiveTintColor: string;
activeIcon: React.Element<*>;
inactiveIcon: React.Element<*>;
}>
How it is used,
return router.getScreenConfig(..).activeIcon;
return router.getScreenConfig(..).inactiveIcon;
router.getScreenConfig
doesn't deal with options passed to iconactiveTintColor
, but for the icon, I have to type it again, and I made a typoPrevious result is the result of previous header function/previous header object
header: (navigation, params, previousResult) => ({
...previousResult,
icon: <Icon name={'settings' + params.focused ? '' : '-outline'} color={params.tintColor} />
});
Flow type,
type NavigationOptionItem<T, U> =
| T
| (navigation: NavigationScreenProp<*,*>, T, U) => T
type HeaderOptionItem = NavigationOptionItem<{
title: string;
icon: React.Element<*>;
}, IconOptions>
How it is used,
return router.getScreenConfig(.., { focused, tintColor }).icon;
getScreenConfig
has to handle the options, limited to objects only, e.g. - getScreenConfig(..., () => {})
is not possible (likely not a significant issue)The docs reference a variable name
in some copy, but the example code actually uses the var name user
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.