As a newbie in react-native i'm trying find a way to use react-navigation with different files without a navbar to navigate (for example just click on a button in the login view to enter the main view, clicking on log out button return to login view).
With react-navigation i made a global component 'Nav' and i placed in the main AppRegistry call:
AppRegistry.registerComponent('myApp', () => Nav);
While in the Navigator.js:
export const Nav = StackNavigator({
Login: { screen: LoginView },
AddStream: { screen: AddStreamView },
});
When i run
react-native run-android
i get the first view loaded under a white space (it should be the navigator, that i don't want in my app)
Now how can i remove the Nav from the view and how can i change View onPress a button component in another file?
There is another package that fill better my desire?
From the docs, setting the the headerMode to none should do the trick. This will hide the header on all of the screens defined in that StackNavigator. Example:
const Nav = StackNavigator({
Login: { screen: LoginView },
AddStream: { screen: AddStreamView },
},{
headerMode: 'none',
});
If you want to control the visibility of the header so that it appears on some of the screens but not all of them, then you can set headerMode to screen and for each individual screen set [the navigation prop for header: { visible: false }. See docs here. For example, if you are creating the screen component in another file, it might look like this:
// In the main file:
const Nav = StackNavigator({
Login: { screen: LoginView },
AddStream: { screen: AddStreamView },
},{
headerMode: 'screen',
});
// Hidden for your Login screen:
export default class LoginView extends Component {
static navigationOptions = {
header: { visible: false }
}
// etc...
}
// Visible for your AddStream screen:
export default class AddStreamView extends Component {
static navigationOptions = {
header: { visible: true }
}
// etc...
}
Edit: missed the second part of your question.
For navigating to a different screen, you really should go through the Hello World tutorial as it explains it. Specifically, this section. Relevant example code from the tutorial:
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello, Chat App!</Text>
<Button
onPress={() => navigate('Chat')}
title="Chat with Lucy"
/>
</View>
);
}
In your case, 'Chat' would be either 'Login' or 'AddStream'.
Related
React Native activeTintColor not getting applied on selected drawer item. My react native navigation routes looks like,
-> DrawerNavigator
-> StackNavigator
-> HomeScreen
-> FirstScreen
-> SecondScreen
-> ThirdScreen
routes.js
const RootStack = createStackNavigator(
{
Home: { screen: HomeScreen },
ChapterGroup: { screen: ChapterGroupScreen },
Chapter: { screen: ChapterScreen },
}
const DrawerStack = createDrawerNavigator(
{
Home: {
screen: RootStack,
params: { id: 1 }
},
Kural: { screen: ChapterGroupScreen, params: { id: 2 } },
Detail: { screen: ChapterGroupScreen, params: { id: 3 } }
}, { contentComponent: DrawerComponent}
}
export default DrawerStack;
I managed to display the First, Second, thirdScreens on the sidebar by creating a new DrawerComponent which will navigate to the appropriate stack screen on drawer item click.
DrawerComponent.js
resetStack = route => {
let pressedDrwaerItem = route.route.key;
let id = route.route.params.id;
this.props.navigation.dispatch(
StackActions.reset({
index: 1,
actions: [
NavigationActions.navigate({
routeName: "Home"
}),
NavigationActions.navigate({
routeName: "ChapterGroup",
params: { title: pressedDrwaerItem, no: id }
})
]
})
);
}
render() {
return (<ScrollView>
<DrawerItems
{...this.props}
onItemPress={this.resetStack}
</DrawerItems</ScrollView>)
}
It properly gets navigated to the ChapterGroup Screen on Home stack but the drawer activeitem points to the Home not the second or third custom name. I think it may be because all the other screen exists inside the Rootstack. Is there anyway to manually set the second drawer item as active?
or any successful implementation of DrawerNavigator inside StackNavigator ? ie. I want to use two screens from stack navigator as drawer items. And if we navigated through to that particular screen from home screen, the corresponding drawer item should be selected.
Not sure whether you have tried contentOptions or not, but this is what i have found from react-navigation document
contentOptions for DrawerItems
There are various property you can use with contentOptions
contentOptions: {
activeTintColor: '#e91e63',
itemsContainerStyle: {
marginVertical: 0,
},
iconContainerStyle: {
opacity: 1
}
}
From above snippet i guess for you activeTineColor might be useful.
I'm not sure about your intentions with the resetStack function.
If you use the following function instead, it's going to work:
navigateToScreen = (route) => {
const navigateAction = NavigationActions.navigate({
routeName: route.route.key
});
this.props.navigation.dispatch(navigateAction);
}
//...
<DrawerItems
{...this.props}
onItemPress={this.navigateToScreen}>
</DrawerItems>
It sets the new screen without stacking it up. It sets the activeTintColor though.
I omitted the params passing to make it simple.
I would like to hide the Back button in the top-left corner, but I don't have any idea how to do it with react-navigation or react-native.
Just tried to use static navigationOptions = { header: null } but the < Back button was still alive.
I was using Modal and it works, but I want to know how to hide < Back button without using Modal.
Thank you in advance!
Using headerLeft: () => <></> works great in iOS, but in Android was still displaying the default back button.
I was able to hide it by adding the headerBackVisible: false on the screenOptions of the Stack Navigator or you could include it on the options for every Stack Screen.
More info at https://reactnavigation.org/docs/native-stack-navigator/#headerbackvisible
I suppose you're using a StackNavigator and that you don't want a header.
You need to use headerMode: none in the StackNavigatorConfig.
For example:
const ModalStack = createStackNavigator(
{
HomeScreen: { screen: Home },
ModalScreen: { screen: Modal },
},
{
headerMode: 'none',
mode: 'modal',
}
);
More info in the react-navigation docs.
It depends upon the react navigation version you're using, try this
const ModalStack = createStackNavigator(
{
HomeScreen: { screen: Home },
ModalScreen: { screen: Modal },
},
{
headerMode: 'none',
header: null
}
);
if it is StackNavigator default config, go to StackNavigator:
defaultNavigationOptions: {
header: null,
},
const Stack = createStackNavigator();
<Stack.Navigator screenOptions={{headerShown: false}}>
createStackNavigator is a function that returns an object containing 2 properties: Screen and Navigator. Both of them are React components used for configuring the navigator.
Now below Stack.Navigator, you can place your screens using <Stack.Screen name="Home" component={HomeScreen} />. In name, you can give any name, and in component give the name of your component.
I am using SwitchNavigator from React-navigation for Authentication in React-native app. In the Authorized Section, I want to show a side Drawer for showing options like settings and log out. Entering into the Authorized section by clicking the button in tabs section user should be able to go to details section of an album. For that, I am using StackNavigator.
Issue:
After Authentication, Once I navigate to a section with Side Drawer in which stack navigator is present, nothing is rendered once navigated to Authorized section. Even the Test screen is mounted(checked through componentDidMount) nothing is displayed.
const Stages = createMaterialTopTabNavigator({
testStage1: { screen: TestScreen },
testStage2: { screen: TestScreen },
testStage3: { screen: TestScreen },
testStage4: { screen: TestScreen },
})
const AuthorizedSectionRouteConf={
navigation:{
stages: {
screen : Stages,
},
details : {
screen: DetailsScreen,
}
},
navigationOptions:{
headerLeft:null
}
}
const AuthorizedSectionNavigator =
createStackNavigator(AuthorizedSectionRouteConf.navigation);
const Config = {
navigation: {
UnauthorizedSection: {
screen: ({navigation}) => <LoginScreen navigate={navigation.navigate}/>,
navigationOptions:{
header:null,
mode:'modal'
}
},
AuthorizedSection: {
screen: createDrawerNavigator({
Home:{
screen: ({navigation}) => <AuthorizedSectionNavigator screenProps={{drawerNavigator:navigation}} />
}
})
},
TestSection: TestScreen
}
}
export default AppNavigator = createSwitchNavigator(Config.navigation);
Navigation after navigation:
this.props.navigate('AuthorizedSection')
==> nothing is visible after this.
However, If I navigate to TestScreen after Authentication which is simple text on screen
it rendered properly.
this.props.navigate('TestSection')
==> working properly
Figured out that there is no space for the component to render. Fixed it by setting the flex property for the parent container.
I started out a bit with react-native, and I'm trying to make a "hello word" app to see how it works.
I made a menu with "tab" at the top of my screen
In the app.js I'm adding the createStackNavigator to set my routes
App.js
import { ... }
const AppNavigator = createStackNavigator({
Main: { screen: Main},
CScreen: {screen: FormCScreen},
});
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<AppNavigator />
);
}
}
This is my main screen, where I set the tabs.
Main.js
imports {AScreen, BScreen} ...
const Tab = createMaterialTopTabNavigator(
{
A: AScreen,
B: BScreen,
},
{
tabBarPosition: 'top',
});
export default class Main extends Component {
render() {
return (
<Tab/>
);
}
}
BScreen.js
Now on one of my BScreen tabs, I want to click on a button, where I hope it loads the screen (CScreen)
imports ...
export default class BScreenextends Component{
render(){
return(
<View>
<TouchableHighlight onPress={() => this.props.navigation.navigate('CScreen')}>
<Text>Click here to open CScreen</Text>
</TouchableHighlight>
</View>
);
}
}
It can render all components correctly, the only problem is that when I click the button to display the CScreen, nothing happens.
It is as if loading the Tab I lost the instacia of my navigator.
Main
Tab
A
B Button (Open CScreen) ~> this is not working
How can I open the screen through a button inside a tab?
[EDIT]
Console.log ScreenB
https://imgur.com/a/teAzpn5
I think your trying to achieve StacksOverTabs mode of navigation setup,
The mistake you made is Main screen being a normal Component inside which you have rendered the Tab Component i.e createMaterialTopTabNavigator. Hence the Tab Component will not get the correct navigation prop from the StackNavigator
Instead, you have to make Main screen itself a createMaterialTopTabNavigator.
For example,
const AppNavigator = createStackNavigator({
Main: { screen: MainTab}, // MainTab is itself a TabNavigator now
CScreen: {screen: FormCScreen},
});
const MainTab = createMaterialTopTabNavigator(
{
A: AScreen,
B: BScreen,
},
{
tabBarPosition: 'top',
});
);
Check out the official examples code in GitHub, inside that navigate to StacksOverTabs
https://github.com/react-navigation/react-navigation/tree/master/examples/NavigationPlayground/js
Thanks.
You could also have put this at the top of your App class I believe:
static router = AppNavigator.router;
There is more information here: https://reactnavigation.org/docs/en/common-mistakes.html#explicitly-rendering-more-than-one-navigator
I want to have a drawer menu in my react-native application. so like you see i'm using stack-navigation of react-native in my code to determinate the routes and a DrawerNavigator which is connected to application in screen field of stack!:
const Application = StackNavigator({
Home: {
screen: Login,
}
,
Profile: {
screen: Profile,
}
});
const easyRNRoute = DrawerNavigator({
Stack: {
screen: Application
}
}, {
contentComponent: DrawerMenu,//<XXXDraw
contentOptions: {
activeTintColor: '#e91e63',
style: {
flex: 1,
paddingTop: 15,
} });
i use Application like </Application> in app.js. my DrawerMenu which is pointed by "//
export default class DrawerMenu extends Component {
render() {
return (
<View>
<Text>Menu</Text>
</View>
);
}
}
and my page -which i want to show menu in that and got problem- contains this codes:
export default class Profile extends React.Component {
static navigationOptions = { header: null };
constructor(props) {
super(props);
this.state = {
active: 'Today',
};
}
navigate() {
this.navigate.navigation.navigate('DrawerOpen'); // open drawer
}
render() {
return (
<View style={styles.countainer}>
<Text style={styles.header}>Profile</Text>
<Button onPress={this.navigate} title="Menu"></Button>
</View>
);
}
}
the problem is this: when i click on the Menu Button. i got this Error:
undefined is not an object (evaluating
'this.props.navigation.navigate')
i tried some codes like :this.props.navigation.navigate('Home'); in component and they are working on but i dont know why it doesn't work on when i take "DrawerOpen" argument in this.navigate.navigation.navigate.
I did some search about that. someones told my remove this.prop in code, but just the error changed to navigation is undefined. i'm stuck in trouble because of this Error. its really lake of obvious tutorial about DrawerMenu in net
Can you use this code:
<Button onPress={() => this.props.navigation.navigate("DrawerOpen")} title="Menu"></Button>
Please read the following:
https://reactjs.org/docs/handling-events.html
A short quote from the website:
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method.
use easyRNRoute insted of Application in your app.js, may be this will work