I am working with React Native createBottomTabNavigator and see that:
lazy - Defaults to true. If false, all tabs are rendered immediately. When true, tabs are rendered only when they are made active for the first time. Note: tabs are not re-rendered upon subsequent visits.
https://reactnavigation.org/docs/bottom-tab-navigator/
Where do I put the attribute "lazy" and set it to false if I want to reload the Connection page every time I click on the Connect navigation tab?
import { createStackNavigator, createAppContainer, createBottomTabNavigator, createSwitchNavigator } from 'react-navigation';
import ...
const RegisterScreens = createSwitchNavigator({
Phone: PhoneLoginScreen,
Register: RegisterScreen
});
const switchNavigator = createSwitchNavigator({
SplashScreen,
TutotialScreen,
loginFlow: createStackNavigator({
Main: MainScreen,
EmailLogin: EmailLoginScreen,
PhoneLogin: RegisterScreens
}),
mainFlow: createBottomTabNavigator({
Home: createStackNavigator({
HomeScreen,
AccountScreen
}),
Connect : ConnectionsScreen,
Chat: createStackNavigator({
AllChatScreen,
SingleChat
})
})
});
const App = createAppContainer(switchNavigator);
export default() => {
return (
<AuthProvider>
<App ref={(navigator)=> {setNavigator(navigator)}}/>
</AuthProvider>
)
};
I am using hooks and want to reload the Connection page because of a callout happening in useEffect()
I have two flows in my app in the main flow.. one is stack navigation and the other is drawer navigation. Stack navigation is working okay but drawer one is giving me this error -
Invariant Violation: The navigation prop is missing for this navigator. In react-navigation version 3 you must set up your app container directly. More info:
https://reactnavigation.org/docs/en/app-containers.html
App.js
import { createAppContainer,
createStackNavigator ,
createBottomTabNavigator,
createDrawerNavigator,
createSwitchNavigator
} from "react-navigation";
import LoginScreen from "./src/screens/LoginScreen";
import RegisterScreen from "./src/screens/RegisterScreen";
import StartScreen from './src/screens/StartScreen';
import { HomeDrawerNavigator } from "./src/components/HomeDrawerNavigator";
const MainNavigator = createSwitchNavigator(
{
loginFlow: {
screen: createStackNavigator(
{
StartScreen :{screen:StartScreen
},
LoginScreen : {screen : LoginScreen},
RegisterScreen : {screen : RegisterScreen}
}
)
},
homeflow: {
screen:HomeDrawerNavigator
}
}
)
const App = createAppContainer(MainNavigator);
export default App;
HomeDrawerNavigator.js
import { createDrawerNavigator } from "react-navigation";
import HomeScreen from "../screens/HomeScreen";
import PolicyScreen from "../screens/PolicyScreen";
export const HomeDrawerNavigator = createDrawerNavigator({
HomeScreen: { screen: HomeScreen },
PolicyScreen: { screen: PolicyScreen }
})
I have also added <HomeDrawerNavigator/> component in my Homescreen.js.
I am new to react native and I am using React navigation 3.x. This is
my project structure.
Mydemo
----routes
--Home.route.js
----src
--pages
--AddUser.js
----App.js
Below I am sharing my route configurations:-
Home.route.js code:-
import { createStackNavigator, createAppContainer } from "react-navigation";
import AddUser from '../src/pages/AddUser';
const HomeStack = createStackNavigator({
Add:{
screen: AddUser
}
})
export default createAppContainer(HomeStack);
App.js Code:-
import {createSwitchNavigator} from 'react-navigation';
import HomeStack from './routes/Home.route';
export default createSwitchNavigator({
Home: HomeStack
}, {
initialRouteName: 'Home',
});
But I am getting this error:-
The navigation prop is missing for this navigator.
can anyone please guide me about what I am doing wrong ?
Thank you.
createAppContainer must be on top of your navigation config =>
Home.route.js
import { createStackNavigator } from "react-navigation";
import AddUser from '../src/pages/AddUser';
export default createStackNavigator({
Add: AddUser
})
App.js
import {createSwitchNavigator, createAppContainer} from 'react-navigation';
import HomeStack from './routes/Home.route';
const AppNavigator = createSwitchNavigator({
Home: HomeStack
}, {
initialRouteName: 'Home',
});
export default createAppContainer(AppNavigator);
I'm learning react native with configuring tabNavigator, DrawerNavigator, and StackNavigator into one without NativeBase or Expo with a single react-navigation library.
I achieved it but there comes an error when I perform some specific sequence in my application.
The application starts with Tab Screen. -> Change Tab -> Open Drawer -> Goto Stack -> open Drawer and then go to Tabs gives this error.
Here is my code :
App.js
import React from 'react';
import {Drawer} from "./src/navigation/MergedNavigator";
import {View,Text} from "react-native";
const App = () => (
<View style={{flex: 1,backgroundColor: '#293656'}}>
<Drawer />
</View>
);
export default App;
MergedNavigator.js
import {DrawerNavigator,StackNavigator,createBottomTabNavigator} from 'react-navigation';
// stack navigation screens
import DetailScreen from '../screens/detail';
import MainScreen from '../screens/main';
import ForgotScreen from '../screens/ForgotScreen';
import RegisterScreen from '../screens/RegisterScreen';
// tab navigator screens
import LoginScreen from '../screens/Login';
import TabOne from '../screens/tabA';
import TabTwo from '../screens/tabB';
//plain
export const stack = StackNavigator({
DetailScreen:{screen:DetailScreen},
MainScreen:{screen:MainScreen}
},{
initialRouteName:'DetailScreen'
});
const secondStack = StackNavigator({
RegisterScreen:{screen:RegisterScreen},
ForgotScreen:{screen:ForgotScreen}
},{
initialRouteName:'ForgotScreen'
})
export const Tabs = createBottomTabNavigator({
Login:{screen:LoginScreen},
TabOne:{screen:secondStack},
TabTwo:{screen:TabTwo}
},{
animationEnabled:true
})
export const Drawer = DrawerNavigator({
Tabs:{screen:Tabs},
Stack:{screen:stack}
})
And all other imported stack screen has nothing but the title.
What's the problem here with my code? Or is there any better way I can achieve these all 3 Navigators with only react-navigation?
There is an issue with the sub actions being reset inside the Stack which can be seen here
Therefore the workaround for this issue would be to wrap your createBottomTabNavigator inside a createStackNavigator with headerMode: none in order to achieve the desired effect.
Info
By adding a StackNavigator nested directly within a DrawerNavigator, the sub actions will be reset only to the StackNavigator defined and won't affect the child screen states, therefore it won't throw the error, as mentioned in the code
if (route.index !== undefined && route.index !== 0) {
subAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({
routeName: route.routes[0].routeName,
}),
],
});
}
MergedNavigator.js
import ForgotScreen from '../screens/ForgotScreen';
import RegisterScreen from '../screens/RegisterScreen';
// tab navigator screens
import LoginScreen from '../screens/Login';
import TabOne from '../screens/tabA';
import TabTwo from '../screens/tabB';
//plain
export const stack = StackNavigator({
DetailScreen:{screen:DetailScreen},
MainScreen:{screen:MainScreen}
},{
initialRouteName:'DetailScreen'
});
const secondStack = StackNavigator({
RegisterScreen:{screen:RegisterScreen},
ForgotScreen:{screen:ForgotScreen}
},{
initialRouteName:'ForgotScreen'
})
export const Tabs = createBottomTabNavigator({
Login:{screen:LoginScreen},
TabOne:{screen:secondStack},
TabTwo:{screen:TabTwo}
},{
animationEnabled:true
})
const TabStack = createStackNavigator({ //... Adding the Stack here
Tabs: {screen: Tabs}
}, {
headerMode: 'none'
})
export const Drawer = DrawerNavigator({
Tabs:{screen:Tab},
Stack:{screen:stack}
})
Here's a modified Snack with header's enabled
import { StackActions, NavigationActions } from 'react-navigation';
let { navigation } = this.props;
let resetAction = StackActions.reset({
key: undefined,
index: 0,
actions: [NavigationActions.navigate({ routeName: 'YourScreen' })],
});
navigation.dispatch(resetAction);
When you set the key to undefined, the navigator uses the actual stack, not the root.
First of all your main issue is you cann't create more than one StackNavigator() on your code.
Please try different navigator for redirection like below example code.
import {DrawerNavigator,StackNavigator,createBottomTabNavigator,createMaterialTopTabNavigator} from 'react-navigation';
// stack navigation screens
import DetailScreen from '../screens/detail';
import MainScreen from '../screens/main';
import ForgotScreen from '../screens/ForgotScreen';
import RegisterScreen from '../screens/RegisterScreen';
// tab navigator screens
import * as TAB from '../tab';
export const stack = StackNavigator({
DetailScreen:{screen:DetailScreen},
MainScreen:{screen:MainScreen}
},{
initialRouteName:'DetailScreen'
});
const secondStack = createMaterialTopTabNavigator({
RegisterScreen:{screen:RegisterScreen},
ForgotScreen:{screen:ForgotScreen}
},{
initialRouteName:'ForgotScreen'
})
export const Tabs = createBottomTabNavigator({
Login:{screen:TAB.Login},
TabOne:{screen:secondStack},
TabTwo:{screen:TAB.TabB}
},{
animationEnabled:true,
initialRouteName:'Login'
})
export const Drawer = DrawerNavigator({
Tabs:{screen:Tabs},
Stack:{screen:stack}
},
{
animationEnabled:true,
initialRouteName:'Tabs'
})
hope above code snippet is useful for you.
I have a Drawer Navigator with 2 screens, Home and Profile. What I need is, when I click in a TouchaleOpacity, change the screen from home to profile, how can I do this?
import { DrawerNavigator } from 'react-navigation';
import JsHome from './JsHome'
import JsProfile from './JsProfile'
const DrawerExample = DrawerNavigator({
JsHome : {
screen: JsHome
},
JsProfile : {
screen: JsProfile
},
}
PS: the TouchableOpacity are in another js file
each screen has navigation props. use this.props.navigation.navigate('JsProfile') in your touchable opacity