Navigate to a screen not defined with createBottomTabNavigator in React Native - react-native

I am trying to navigate to a screen that I have not defined with createBottomTabNavigation as I don't want it to be shown on the bottom tab navigation.
To try so I have created the component separately:
class SingleScreen extends React.Component {
render() {
return (
<View>
<Text>This is sigle screen</Text>
</View>
);
}
}
To navigate to this screen:
render () {
const {navigate} = this.props.navigation;
return(
<TouchableHighlight onPress={() => navigate('SingleScreen', {id: 'id', from: 'Search'})}>
//Code
</TouchableHighlight>
);
}
But is not working. Do I have to describe this screen with createBottomTabNavigator? If so, is it possible to hide from appearing on the tab bar?

You need to make some change in app.js. add createBottomTabNavigator inside createStackNavigator. Add those component into stacknavigator in which you do not want to add into bottom tab navigator. In createBottomTabNavigator add those component which you want to show in tab bar
Please check following code
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
SafeAreaView,
ScrollView,
Dimensions
} from "react-native";
import { createStackNavigator, createDrawerNavigator } from "react-navigation";
import LoginScreen from "./Screens/LoginScreen";
export default class App extends Component {
render() {
return <StackNav />;
}
}
const StackNav = createStackNavigator(
{
TabNavigator: {
screen: AppTabNavigator,
navigationOptions: {
headerMode: "none",
header: null
}
},
SingleScreen: {
screen: SingleScreen,
navigationOptions: {
headerMode: "none",
header: null
}
},
SecondScreen: {
screen: SecondScreen,
navigationOptions: {
headerMode: "none",
header: null
}
}
},
{
initialRouteName: "TabNavigator"
}
);
const AppTabNavigator = createBottomTabNavigator({
Login: {
screen: LoginScreen
}
});

Related

undefined is not an object (evaluating '_this.props.navigation.navigate') upon button click

I am fairly new to react-native and react-navigation and trying to move from one screen to another via button click, keep getting this error. I've found similar questions here on SO (this and this) but they don't work for me, keep getting this error.
What I am doing is, I have an App.js that is the initial screen which for now shows a login form (called Splash):
import React from 'react';
import {
View,
ActivityIndicator,
StyleSheet
} from 'react-native';
import { createDrawerNavigator, createAppContainer } from "react-navigation";
import HomeScreen from './HomeScreen';
import ProfileScreen from './ProfileScreen';
import Splash from './Splash';
export default class App extends React.Component {
render() {
const { navigation } = this.props;
return (
<View>
<Splash navigation={navigation}/>
</View>
);
}
}
const AppNavigator = createDrawerNavigator({
Home: {
screen: HomeScreen
},
Profile: {
screen: ProfileScreen
}
}, {
initialRouteName: "Home",
contentOptions: {
activeTintColor: '#e91e63'
}
});
const AppContainer = createAppContainer(AppNavigator);
On my Splash screen I now have no functionality as I am just trying to get it to move to my HomeScreen when I hit the Login button:
import React, { Component } from 'react';
import {
ScrollView,
Text,
TextInput,
TouchableOpacity,
StyleSheet
} from 'react-native';
class Splash extends Component {
constructor(props) {
super(props);
}
render() {
return (
<ScrollView style={{padding: 20}}>
<TextInput autoCapitalize="none"
onSubmitEditing={() => this.passwordInput.focus()}
autoCorrect={false}
keyboardType='email-address'
returnKeyType="next"
placeholder='Email address'
placeholderTextColor='rgba(225,225,225,0.7)'/>
<TextInput returnKeyType="go"
ref={(input)=> this.passwordInput = input}
placeholder='Password'
placeholderTextColor='rgba(225,225,225,0.7)'
secureTextEntry/>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Home')}>
<Text>LOGIN</Text>
</TouchableOpacity>
</ScrollView>
)
}
};
export default Splash;
What happens now is that as soon as I hit the login button, I get the error in the title. Any clues on what I am doing wrong?
Remove App component, you don't need it in this case. Make Splash as your initial screen
const AppNavigator = createDrawerNavigator({
Splash: {
screen: Splash
},
Home: {
screen: HomeScreen
},
Profile: {
screen: ProfileScreen
}
}, {
initialRouteName: "Splash",
contentOptions: {
activeTintColor: '#e91e63'
}
});
then export AppContainer directly
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer

How to make screen or component on top of other screens

I'm making a music app and what I want to do is to implement a music player screen that can be active on all other screens something like this:
https://reactnativeexample.com/react-native-swipe-up-down-component/
This is my app.js:
import React, {Component} from 'react';
import { createDrawerNavigator, createStackNavigator, createAppContainer } from "react-navigation";
import HomeScreen from './screens/home';
import SideBar from './screens/sidebar';
import SongScreen from './screens/song';
const Drawer = createDrawerNavigator(
{
Home: {screen: HomeScreen}
},
{
initialRouteName: "Home",
contentOptions: {
activeTintColor: "#e91e63"
},
contentComponent: props => <SideBar {...props} />
}
);
const AppNavigator = createStackNavigator(
{
Drawer: { screen: Drawer },
SongScreen: { screen: SongScreen }
},
{
initialRouteName: "Drawer",
headerMode: "none"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default class App extends Component {
render() {
return (
<AppContainer />
);
}
}
use https://github.com/octopitus/rn-sliding-up-panel and make your root screen look like this:
<View>
<AppContainer/>
<SlidingUpPanel/>
</View

DrawerNavigator - Can't open DrawerNavigator inside StackNavigator route

recently I have a problem on a simple DrawerNavigator inside StackNavigator. My goal is to get both the back function from StackNavigator and DrawerNavigator side menu when I click BurgerMenu icon on the StackNavigator's header.
Here's my current code
import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';
import SvgUri from 'react-native-svg-uri';
import { StackNavigator } from 'react-navigation';
import { DrawerNavigator } from "react-navigation";
import SideBar from './SideBar';
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import Screen3 from './Screen3';
export default class App extends React.Component {
render() {
return <StackNav />;
}
}
class BurgerMenu extends React.Component {
render() {
return (
<TouchableHighlight
onPress={() => this.props.navigation.navigate("DrawerOpen")}>
<SvgUri
width="30"
height="30"
source={require("Project_01/app/images/menu.svg")}
/>
</TouchableHighlight>
);
}
}
const DrawerNav = DrawerNavigator(
{
Screen1: { screen: Screen1 }
},
{
contentComponent: props => <SideBar {...props} />
}
);
const StackNav = StackNavigator(
{
Screen1: {
screen: DrawerNav,
},
Screen2: {
screen: Screen2,
},
Screen3: {
screen: Screen3,
},
},
{
initialRouteName: 'DrawerNav',
navigationOptions: {
headerRight: <BurgerMenu /> ,
title: "Header"
},
},
);
As you can see Im adding headerRight with BurgerMenu component to navigationOptions in StackNavigator.
In BurgerMenu class I added TouchableHighlight with " onPress={() => this.props.navigation.navigate("DrawerOpen")}> " which I mean open up the DrawerNavigator.
Unfortunately when I press that, i got an error message says "undefined is not an object (evaluating 'e.props.navigation.navigate').
Can someone help me please
Try changing this:
navigationOptions: {
headerRight: <BurgerMenu /> ,
title: "Header"
},
by this:
navigationOptions: ({navigation}) => ({
headerRight: <BurgerMenu navigation={navigation} />,
title: "Header"
}),
Also you can refer to this example on my github.

Changing tab bar background color causes all screens to re-render

I am using react-navigation as my navigation solution. I need to change the background color of my tab bar on click of a button in the settings screen, however, do so would make all screens re-render, here's a live demo of what's going on:
As you can see, every time I press the Change Tab Bar Background Color button in Settings screen, the color of the tab bar changes, however, at the same time, the app automatically navigates to Login screen for some reason. I am using redux to maintain the current theme, here are the code:
Action creator:
export function switchTheme() {
return { type: 'SWITCH_THEME' };
}
Reducer:
const INITIAL_STATE = {
backgroundColor: 'white'
};
export default function (state = INITIAL_STATE, action) {
switch (action.type) {
case 'SWITCH_THEME':
return { backgroundColor: state.backgroundColor === 'white' ? 'black' : 'white' };
default:
return state;
}
}
Settings screen:
import React, { Component } from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import { Icon } from 'react-native-elements';
import { connect } from 'react-redux';
import { switchTheme } from '../actions';
class SettingsScreen extends Component {
static navigationOptions = {
title: 'Settings',
header: null,
tabBarIcon: ({ tintColor }) => {
return (<Icon name='settings' size={30} color={tintColor} />);
}
};
render() {
return (
<View style={{ ... }}>
<TouchableOpacity
onPress={this.props.switchTheme}
style={{ ... }}
>
<Text style={{ ... }}>
Change Tab Bar Background Color
</Text>
</TouchableOpacity>
</View>
);
}
}
export default connect(null, { switchTheme })(SettingsScreen);
Main.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { TabNavigator } from 'react-navigation';
import WelcomeScreen from './screens/WelcomeScreen';
import LoginScreen from './screens/LoginScreen';
import RegisterScreen from './screens/RegisterScreen';
import SettingsScreen from './screens/SettingsScreen';
import MessageScreen from './screens/MessageScreen';
class Main extends Component {
render() {
const MainTabNavigator = TabNavigator({
login: { screen: LoginScreen },
register: { screen: RegisterScreen },
message: { screen: MessageScreen },
setting: { screen: SettingsScreen }
}, {
tabBarOptions: {
style: { backgroundColor: this.props.backgroundColor }
}
});
return (
<MainTabNavigator />
);
}
}
const mapStateToProps = state => {
const { backgroundColor } = state.theme;
return { backgroundColor };
};
export default connect(mapStateToProps, null)(Main);
App.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Main from './Main';
class App extends Component {
render() {
return (
<Provider store={store}>
<Main />
</Provider>
);
}
}
export default App;
Why does the app navigates to Login screen and what can I do to prevent this from happening?
the backgroundcolor piece of state is changed in the reducer SWITCH_THEME
so I think when it comes to the main.js and pull out the backgroundColor from state.theme the prop backgroundColor gets updated and it re-renders

react-native-navigation cant navigate to another page

I searched and compare it to proper solutions nothing look wrong but I almost get the error screen shown below;
Whats wrong with navigation code here;
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import About from './app/components/About';
export default class Home extends Component {
static navigationOptions = {
title: 'Welcome',
};
navigateToAbout(){
const { navigate } = this.props.navigation;
navigate('About')
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=>this.navigateToAbout()}>
<Text>Go to About Page</Text>
</TouchableOpacity>
</View>
);
}
}
const SimpleApp = StackNavigator({
Home: { screen: Home },
About: { screen: About },
});
AppRegistry.registerComponent('SimpleApp', () => SimpleApp);
I think your code is fine unless you have to bind the method (usually I use an arrow function, but it's ok if you want to bind the method in you constructor), maybe you can try like this way:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import About from './app/components/About';
export default class Home extends Component {
static navigationOptions = {
title: 'Welcome',
}
navigateToAbout = () => {
this.props.navigation.navigate('About');
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<TouchableOpacity onPress={ this._navigateToAbout }
<Text>Go to About Page</Text>
</TouchableOpacity>
</View>
);
}
}
const SimpleApp = StackNavigator({
Home: { screen: Home },
About: { screen: About },
});
AppRegistry.registerComponent('SimpleApp', () => SimpleApp);
I hope it can help you :)
You didn't connect your home component with navigation, you should pass navigation method to the mapDispatchToProps object of connect method.
Here is an example:
import { connect } from 'react-redux'
import { NavigationActions } from 'react-navigation'
const navigate = NavigationActions.navigate
export class Home extends Component {
static navigationOptions = ({ navigation }) => ({
title: 'Welcome',
})
static propTypes = {
navigate: T.func.isRequired,
}
navigateToAbout(){
const { navigate } = this.props.navigation;
navigate({ routeName: 'About' })
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={()=>this.navigateToAbout()}>
<Text>Go to About Page</Text>
</TouchableOpacity>
</View>
);
}
}
export default connect(null, { navigate })(Home)