Hi friends I am scratching my head with react-navigation from last 2 days, I tried many things(documentation doesn't seems that clear for a beginner), so right now I am facing few problem that seems little complex to me and hence I seek advice and help to proceed further.following are the cases/problem/scenario I seek help for -
react-navigation does not cover the header and statusbar, I wanted to achieve something like gmail but I ended up with like this
I used following code blocks to reach to this point
import React, {Component} from 'react';
import { AppRegistry, View, BackAndroid, StatusBar,} from 'react-native';
import {
NavigationActions,
addNavigationHelpers,
StackNavigator,
DrawerNavigator
} from 'react-navigation';
import LandingScreen from 'src/screens/landingScreen';
import Login from 'src/screens/login'
import SignUp from 'src/screens/signUp'
import ForgotPassword from 'src/screens/forgotPassword'
import Dashboard from 'src/screens/dashboard'
import UserProfile from 'src/screens/userProfile'
export const Drawer = DrawerNavigator({
Dashboard:{
path:'/',
screen:Dashboard,
},
UserProfile:{
path:'/'
screen:UserProfile
},
}, {
initialRouteName: 'Dashboard',
contentOptions: {
activeTintColor: '#e91e63',
},
headerMode: 'screen',
});
const routesConfig = {
Landing:{screen:LandingScreen},
Login: { screen: Login },
SignUp: { screen: SignUp },
ForgotPassword: { screen: ForgotPassword },
Drawer:{screen:Drawer}
};
export const AppNavigator = StackNavigator(routesConfig, {
initialRouteName: 'Drawer'
});
AppRegistry.registerComponent('Riduk', () => AppNavigator);
Other problem is how should I add 2 drawers in my app at the same screen
Here is a simplified example:
const FooStackNavigator = StackNavigator({
Foo: {
screen: FooScreen,
navigationOptions: {
title: 'Foo',
}
},
});
const BarStackNavigator = StackNavigator({...});
const MyDrawerNavigator = DrawerNavigator({
FooStack: {
screen: FooStackNavigator,
navigationOptions: {
drawer: () => ({
label: 'Foo',
})
},
},
BarStack: {
screen: BarStackNavigator,
navigationOptions: {
drawer: () => ({
label: 'Bar',
})
},
}
});
const AppNavigator = StackNavigator({
Drawer: { screen: MyDrawerNavigator },
}, {
headerMode: 'none',
});
There is an issue for Header in DrawerNavigator.
But you can fix by using StackNavigator inside DrawerNavigator
export const Drawer = DrawerNavigator({
Dashboard:{
path:'/',
screen: StackNavigator( { Screen1: {
screen: Dashboard
}})
},
UserProfile:{
path:'/',
screen: StackNavigator( { Screen1: {
screen: UserProfile
}})
},
}});
Then set headerMode: 'none' to root StackNavigator
export const AppNavigator = StackNavigator(routesConfig, {
headerMode: 'none'
});
Here, AppNavigator is root StackNavigator and routesConfig has above DrawerNavigator and other screens.
Is this the issue you're trying to resolve?
https://blog.callstack.io/android-drawer-statusbar-done-right-for-react-native-7e85f01fc099
As per my knowledge, you have to do 2 things:
1. Put drawer control at the top of navigation stack.
2. Set translucent propery of StatusBar
<StatusBar
translucent
backgroundColor="rgba(0, 0, 0, 0.24)"
animated
/>
{ Platform.OS === 'android' && Platform.Version >= 20 ?
<View
style={{
height: 24,
backgroundColor: "#512DA8",
}}
/>
: null }
Kindly let me know if it does work.
DrawerNavigator must over on StackNavigator, this is my way to fix this:
const navStack = StackNavigator({
Home: { screen: Main, },
Example01: { screen: Example01, },
Example02: { screen: Example02, },
});
const navDrawer = DrawerNavigator({
Home: {
screen: navStack, // Drawer over on StackNavigator
navigationOptions: {
drawerLabel: 'Home',
header: null,
}
},
Example03: {
screen: Example03,
navigationOptions: {
drawerLabel: 'Example03',
}
},
},
{
headerMode: 'none',
headerVisible: false,
navigationOptions: {
header: null
}
});
Hope this helps.
Related
I got the following react-navigation structure :
<NavigationContainer>
{authToken ? (
<Tab.Navigator>
<Tab.Screen
name='HomeScreen'
component={HomeScreen}
/>
<Tab.Screen
name='SettingsScreen'
component={SettingsScreen}
/>
</Tab.Navigator>
) : (
<Stack.Navigator>
<Stack.Screen name="SignUpScreen" component={SignUpScreen} />
</Stack.Navigator>
)}
</NavigationContainer>
How to navigate from SignUpScreen to HomeScreen and conversely :
// HomeScreen.js button :
onPress={() => {
// remove authToken and then :
navigation.navigate(`SignUpScreen`);
}}
Got the error message : The action 'NAVIGATE' with payload {"name":"SignUpScreen"} was not handled by any navigator. Do you have a screen named 'SignUpScreen'?
Same from SignUpScreen after authToken = true.
Is there a way to navigate from one stack to another in a ternary operator ? (Or trigger the index of the navigation to re-render the condition ?).
Assuming what what you want to implement is an App that has a different navigation if you are logged in or out, I would suggest using the Switch navigator. In your case, your error it is most likely caused because the signup screen does not exist in the tree of both stack navigators. I'll post the entire main code but the part you should take a look is this:
const Navigator = createSwitchNavigator({
Main: MainTabNavigator,
Auth: AuthNavigator,
SplashScreen: SplashScreen,
Onboarding: Onboarding,
}, {
initialRouteName: 'SplashScreen',
headerMode: 'none'
});
The rest:
import React from "react";
import { createStackNavigator, createBottomTabNavigator, createSwitchNavigator, createAppContainer } from 'react-navigation';
import {ThemeProvider} from 'styled-components'
import {configureStore} from "./redux/store"
import { Provider } from 'react-redux'
const theme = {
primaryColor: '#3F51B5',
darkPrimaryColor: '#303F9F',
containerBackgroundColor: '#FFFFFF',
lightPrimaryColor: '#C5CAE9',
accentColor: '#FF5722',
backgroundColor: 'white',
font: 'Lato-Regular',
fontBold: 'Lato-Bold'
}
const ConfigNavigator = createStackNavigator({
Config: ConfigScreen,
SettingsScreen: SettingsScreen,
...coreRoutes
}, {
initialRouteName: 'Config',
headerMode: 'none'
});
const HomeNavigator = createStackNavigator({
...coreRoutes
}, {
initialRouteName: 'HomeScreen',
headerMode: 'none'
});
const PlacesNavigator = createStackNavigator({
Places: PlacesScreen,
POI: POIScreen,
}, {
initialRouteName: 'Places',
headerMode: 'none'
});
const PinnedNavigator = createStackNavigator({
Pinned: PinnedScreen,
POI: POIScreen,
}, {
initialRouteName: 'Pinned',
headerMode: 'none'
});
const MainTabNavigator = createBottomTabNavigator({
Home: HomeNavigator,
Places: PlacesNavigator,
Pinned: PinnedNavigator,
Chat: ChatScreen,
Config: ConfigNavigator,
}, {
initialRouteName: 'Home',
tabBarPosition: "bottom",
swipeEnabled: false,
tabBarComponent: props => {
return <TabNavigation {...props}
items={[
{
text: Strings['home'], icon: { name: "home", type: "MaterialCommunityIcons" },
route: "Home"
},
{
text: Strings['places'], icon: { name: "map-marker-multiple", type: "MaterialCommunityIcons"},
route: "Places"
},
{
text: Strings['pinned'], icon: { name: "pin", type: "MaterialCommunityIcons" },
route: "Pinned"
},
{
text: Strings['chat'], icon: { name: "wechat", type: "MaterialCommunityIcons" },
route: "Chat"
},
{
text: Strings['settings'], icon: { name: "settings", type: "MaterialCommunityIcons" },
route: "Config"
}
]}
/>
}
});
const AuthNavigator = createStackNavigator({
Registration: RegistrationScreen,
}, {
initialRouteName: 'Registration',
headerMode: 'none'
});
const Navigator = createSwitchNavigator({
Main: MainTabNavigator,
Auth: AuthNavigator,
SplashScreen: SplashScreen,
Onboarding: Onboarding,
}, {
initialRouteName: 'SplashScreen',
headerMode: 'none'
});
const AppContainer = createAppContainer(Navigator)
let store = configureStore();
class App extends React.Component {
constructor(){
super();
this.theme = new Theme(theme);
}
render(){
return <Provider store={store}>
<ThemeProvider theme={this.theme.getTheme()}>
<AppContainer/>
</ThemeProvider>
</Provider>
}
};
export default App;
From then, you just navigate to Auth or Main and the entire navigator tree changes.
I want to know how to combine bottom tab navigator with Stack Navigator on Home Navigator in app.js
Here is my code
import React from 'react';
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import Signup from './screens/signup';
import Login from './screens/login';
import Home from './screens/Home';
import Loading from './screens/Loading';
import Welcome from './screens/Welcome';
import ForgotPassword from './screens/ForgotPassword';
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
const navigator = createStackNavigator({
loading: {
screen: Loading,
navigationOptions: {
headerShown: false,
headerTransparent: true,
},
},
Welcome: {
screen: Welcome,
navigationOptions: {
headerShown: false,
headerTransparent: true,
},
},
signup: {
screen: Signup,
navigationOptions: {
headerShown: false,
headerTransparent: true,
},
},
login: {
screen: Login,
navigationOptions: {
headerShown: false,
headerTransparent: true,
},
},
Home: {
screen: Home,
navigationOptions: {
headerShown: false,
headerTransparent: true,
},
},
InitialRouteName: Loading,
});
const AppContainer = createAppContainer(navigator);
Any suggest to add bottom tab navigator in this code? I want to know how to combine Tab bottom navigator with stack navigator in app.js (calling home with bottom tab navigator)
thanks
You can create a tabNavigator and set it like any other route.
Obs: Also work for drawerNavigator.
Example:
const MainTab = TabNavigator(tabs, {
initialRouteName: initialRouteName,
tabBarPosition: "bottom",
});
const RootNavigator = StackNavigator(
{
Root: {
screen: MainTab,
navigationOptions: {
headerMode: "none"
}
},
/* Other Screens */
Login: { screen: LoginScreen },
}
)
const AppContainer = createAppContainer(RootNavigator);
Obs: this also work for drawerNavigator.
i am trying to use stack navigation and tab navigation at the same time,i have created a stack navigator and tabs in my app.js files but whenever my app loads they are showing different pages at the same time and i don,t know how to resolve this issue. my app.js code is
import { createStackNavigator, createAppContainer } from 'react-navigation';
import IntroSlides from './src/screens/introslides/introslides';
import Dashboard from './src/screens/dashboard/dashboard';
import InboxScreen from '../screens/inbox/inbox';
import Favourites from '../screens/favourite/favourite';
const MainNavigator = createStackNavigator({
dashboard: { screen: Dashboard },
intro: { screen: IntroSlides },
}, {
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
const TabNavigator = createBottomTabNavigator({
// dashboard: { screen: Dashboard },
Inbox: { screen: InboxScreen },
Favourites: { screen: Favourites }
});
const App = createAppContainer(MainNavigator);
export default App;
when the app loads both the stack shows pages at the same time ,any Help would be appreciated
Here is an example to use tab navigator and stack navigator together:
const Stylelist = StackNavigator({
Login: {
screen: LoginScreen,
navigationOptions: ({ navigation }) => ({
header: null,
}),
},
Register: {
screen: RegisterScreen,
navigationOptions: ({ navigation }) => ({
header: null,
}),
},
Home: {
screen: TabNavigator({
Home: {
screen: HomeScreen,
navigationOptions: ({ navigation }) => ({
title: 'Home',
}),
},
Friends: {
screen: FriendsScreen,
navigationOptions: ({ navigation }) => ({
title: 'My Friends',
}),
},
}),
navigationOptions: ({ navigation }) => ({
title: 'Home',
}),
},
});
export default Stylelist;
I have this code:
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import HomeScreen from './modules/Home/HomeScreen';
import DetailScreen from './modules/Home/DetailScreen';
import React from 'react';
const tabNav = createBottomTabNavigator(
{
Home: {
screen: HomeScreen,
},
Details: { screen: DetailScreen },
},
);
//
tabNav.navigationOptions = ({ navigation }) => {
let { routeName } = navigation.state.routes[navigation.state.index];
console.log('navigation: ', navigation.state);
let title;
if (routeName === 'Home') {
title = 'Home';
} else if (routeName === 'Details') {
title = 'Detail';
}
return {
title,
headerMode: 'none',
};
};
//
const RootNavigator = createStackNavigator(
{
Main: tabNav,
},
{
navigationOptions: {
headerMode: 'none',
headerTransparent: true,
},
},
);
export default RootNavigator;
This is code is working well.
My question is, I want to change this section become dynamic. I've tried to put stackNavigator inside the tab but keep returning me error.
if (routeName === 'Home') {
title = 'Home';
} else if (routeName === 'Details') {
title = 'Detail';
}
Any suggestion?
Update:
I've tried to put stackNavigator inside my screen:
const tabNav = createBottomTabNavigator(
{
Home: createStackNavigator({
screen: HomeScreen,
navigationOptions: {
title: 'Home 2',
},
}),
Details: { screen: DetailScreen },
},
);
It keeps return me The component for route 'navigationOptions' must be a React component.
the StackNavigator is misconfigured, try this :
const tabNav = createBottomTabNavigator({
Home: {
screen: createStackNavigator({
homeSreen: {
screen: HomeScreen,
navigationOptions: {
title: 'Home 2',
},
},{
initialRouteName: 'homeScreen',
})
},
Details: { screen: DetailScreen },
});
or
const HomeStack = createStackNavigator({
home: {
screen: HomeScreen,
navigationOptions: {
title: 'Home 2',
},
},
},{
initialRouteName: 'home',
});
const tabNav = createBottomTabNavigator({
Home: { screen: HomeStack },
Details: { screen: DetailScreen },
});
and
https://reactnavigation.org/docs/en/stack-navigator.html
and you can set title per screen:
const tabNav = createBottomTabNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: {
title: 'Home',
},
},
Details: {
screen: DetailScreen,
navigationOptions: {
title: 'Details',
},
},
},
);
https://reactnavigation.org/docs/en/tab-navigator.html#navigationoptions-for-screens-inside-of-the-navigator
I am using stack navigator inside the drawer navigator. What I want to do is, I need to know the activeItem (the active screen), so as to display it as active.
StackNavigator
const stackNav = StackNavigator({
homeComponent: { screen: HomeScreen },
serviceScreen: { screen: ServiceScreen },
serviceDetailScreen: { screen: ServiceDetailScreen },
selectVehicleScreen: { screen: SelectVehileScreen },
addEditVehicle: { screen: AddVehicle },
dateTimeScreen: { screen: DateTimeScreen },
reviewScreen: { screen: ReviewScreen },
notesScreen: { screen: NotesScreen },
}, {
headerMode: 'none'
});
DrawerNavigator
const DrawerStack = DrawerNavigator({
appointment: {
screen: stackNav,
},
}, {
headerMode: 'none',
gesturesEnabled: false,
contentComponent: DrawerContainer
});
export default DrawerStack;
What you can do is
In your context there is only one screen that can be active and that is appointment screen.
If you want to know that if appointment screen is focused then you should check the props inside the DrawerContainer Component. It will give you the activeItemKey i.e appointment.
And then you can simply check in DrawerComponent that if
this.props.activeItemKey === 'appointment' ? { color: '#000' } : { color: '#fff' }]}
You can also pass the activeTintColor prop from DrawerNavigator as shown below
You can find other DrawerNavigatorConfigs here
const DrawerStack = DrawerNavigator({
appointment: {
screen: stackNav,
},
}, {
headerMode: 'none',
gesturesEnabled: false,
contentComponent: DrawerContainer,
contentOptions: {
activeTintColor: '#e91e63',
itemsContainerStyle: {
marginVertical: 0,
},
iconContainerStyle: {
opacity: 1
}
}
});
export default DrawerStack;