I am trying to customize drawer navigator in my app. I am using react-navigation. When first time I've inserted this code it showed just white screen and even navigation links were disappeared after making few things it showed this error screen.
Before that it showed just white screen inside drawer without my links. Here is the code.
App.js
import React from 'react';
import {StyleSheet, Text, View } from 'react-native';
import WelcomeScreen from './screens/WelcomeScreen';
import SigninScreen from './screens/SigninScreen';
import SignupScreen from './screens/SignupScreen';
import HomeScreen from './screens/HomeScreen';
import FoodScreen from './screens/FoodScreen';
import RestaurantsScreen from './screens/RestaurantsScreen';
import ProfileScreen from './screens/ProfileScreen';
import FavoritesScreen from './screens/FavoritesScreen';
import SettingsScreen from './screens/SettingsScreen';
import { TabNavigator, DrawerNavigator, StackNavigator,contentComponent } from 'react-navigation';
import {DrawerContent} from './components/DrawerContent'
export default class App extends React.Component {
render() {
const MainNavigator = TabNavigator({
welcome: { screen: WelcomeScreen },
signin: { screen: SigninScreen },
signup: { screen: SignupScreen },
main: {
screen: DrawerNavigator({
home: { screen: HomeScreen },
food: { screen: FoodScreen },
restaurants: { screen: RestaurantsScreen },
profile: {
screen: StackNavigator({
profilw: { screen: ProfileScreen },
settings: { screen: SettingsScreen }
})
}
},
{
contentComponent: props => <DrawerContent {...props} />,
}
)
}
},
);
return (
<MainNavigator />
);
}
}
DrawerContent.js
import React, { Component } from "react";
import { View, ScrollView,Button,Text } from "react-native";
class DrawerContent extends Component {
render() {
return (
<ScrollView style={styles.container}>
<View style={{ flex: 1 }}>
<Button transparent info onPress={() => { this.handlechange(); }}>
<Text style={{ fontSize: 16 }}>Change Email</Text>
</Button>
</View>
</ScrollView>
);
} }
const styles = {
container: {
flex: 1,
padding: 20,
backgroundColor: 'Green',
}, };
export default DrawerContent;
The button you are using is the button that should be imported from the
native base , as you are using the style property for that , or simply used this instead of that button code , replace it with below one
<Button onPress={() => { this.handlechange(); }} title="Learn More" color="#841584" />
Using this will help you with that
I think it's because contentComponent expects a class component, instead of using react-navigation, use react-navigation-drawer to import createDrawerNavigaor and DrawerNavigatorItems
Related
Suppose you have a react native app that has a flow that navigates between screens upon data entry, how would you navigate through these screens without having to add these screens to a stackNavigation or createbottomtabnavigator?
For example here is my app upon being on home page.
1)
2)
3) It gets added to navigation tab menu :(
here is the navigation code.
import React from "react";
// import HomeView from "./components/screens/Home";
import AddPostView from "./containers/addPost";
import SettingsView from "./containers/settings";
import ContentView from "./components/screens/AddContent";
import Icon from "react-native-vector-icons/AntDesign";
import { createAppContainer } from "react-navigation";
import DashboardView from "./components/screens/Dashboard";
import { createMaterialBottomTabNavigator } from "react-navigation-material-bottom-tabs";
const AppNavigator = createMaterialBottomTabNavigator(
{
Home: {
screen: AddPostView, // shows the title screen is there a way i can nest the screens apart of this screen ?
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="home" color={tintColor} size={24} />
)
}
},
Content: {
screen: ContentView, // shows add content screen.
labeled: false,
navigationOptions: {
tabBarIcon: false,
tabBarLabel: false
}
},
Dashboard: {
screen: DashboardView,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="dashboard" color={tintColor} size={24} />
)
}
},
Settings: {
screen: SettingsView,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="user" color={tintColor} size={24} />
)
}
}
},
{
initialRouteName: "Home",
activeColor: "#f0edf6",
tabBarLabel: "Content",
inactiveColor: "#333333",
barStyle: {
backgroundColor: "#B9D2B1",
justifyContent: "center",
alignItems: "center"
}
}
);
export default createAppContainer(AppNavigator);
AddPost.jsx
import React, { Component, Fragment } from "react";
import { View, Text, Button, StyleSheet } from "react-native";
import { Subheading, Dialog } from "react-native-paper";
import PostForm from "../forms/createPost/createPost";
export default class AddPostView extends Component {
state = {
title: "",
content: "",
touched: {
title: false,
content: false
}
};
titleChange = title => {
this.setState({ title });
};
validate = field => {
console.log("tet", field);
this.setState({
touched: { ...this.state.touched, [field]: true }
});
console.log(this.state.touched);
};
contentChange = content => {
this.setState({ content });
};
render() {
const isEnabled = this.state.title.length > 6 ? false : true;
return (
<Fragment>
<Subheading style={styles.labels}> Add An Entry</Subheading>
<PostForm
title={this.state.title}
titleChange={this.titleChange}
disButton={isEnabled}
hasError={this.state.touched}
onSubmit={() => this.props.navigation.navigate("Content")}
validateTitle={() => this.validate("title")}
/>
</Fragment>
);
}
}
const styles = StyleSheet.create({
labels: {
textAlign: "center",
fontWeight: "bold",
fontSize: 25,
padding: 20,
marginTop: 50
}
});
I found a way to do this. Here were my steps
1) Create a new file called otherNav.jsx (this can handle multiple screens for different scenarios, for now i just need it to navigation to a form)
import React from "react";
import { createStackNavigator } from "react-navigation-stack";
import { createAppContainer } from "react-navigation";
import ContentView from "./containers/addContent";
import Icon from "react-native-vector-icons/AntDesign";
const OtherNavigation = createStackNavigator(
{
Content: {
screen: ContentView
}
},
{
headerMode: "none",
activeColor: "#f0edf6",
tabBarLabel: "Content",
inactiveColor: "#333333",
barStyle: {
backgroundColor: "#B9D2B1",
justifyContent: "center",
alignItems: "center"
}
}
);
export default createAppContainer(OtherNavigation);
2) Call this in AuthNav where all the navigations live
import React, { Component } from "react";
import { createAppContainer } from "react-navigation";
import AuthLoadingScreen from "./AuthLoadingScreen";
import AuthNavigation from "./splashNav";
import AppNavigator from "./loggedInNav";
import OtherNavigation from "./otherNav";
import { createStackNavigator } from "react-navigation-stack";
export default createAppContainer(
createStackNavigator(
{
AuthLoading: {
screen: AuthLoadingScreen // intimidiary between App && Auth checks for token and such
},
App: AppNavigator,
Content: OtherNavigation,
Auth: AuthNavigation
},
{
initialRouteName: "AuthLoading",
headerMode: "none"
}
)
);
3) Now this will flow accordingly
render() {
const isEnabled = this.state.title.length > 6 ? false : true;
return (
<Fragment>
<Subheading style={styles.labels}> Add An Entry</Subheading>
<PostForm
title={this.state.title}
titleChange={this.titleChange}
disButton={isEnabled}
hasError={this.state.touched}
onSubmit={() => this.props.navigation.navigate("Content")}
validateTitle={() => this.validate("title")}
/>
</Fragment>
);
}
}
So now we have this (end result its not added to bottomNav)
1)
2)
react-navigation, navigation.navigate is not working in my component and does not show any error.
here is my navigator shopNavigation component:
import {createStackNavigator} from 'react-navigation-stack';
import {createAppContainer} from 'react-navigation';
import {Platform} from 'react-native';
import ProducOverviewScreen from '../screens/shop/ProductOverviewScreen';
import ProductDetailScreen from '../screens/shop/ProductDetailScreen';
import Colors from '../constants/Colors';
const ProductNavigator = createStackNavigator(
{
ProductOverview: ProducOverviewScreen,
ProductDetail: ProductDetailScreen
},
{
defaultNavigationOptions: {
headerStyle: {
backgroundColor: Platform.OS === 'android' ? Colors.primary: '',
},
headerTinColor: Platform.OS === 'android' ? 'white' : Colors.primary,
},
},
);
export default createAppContainer(ProductNavigator);
and this is the component i want to do the navigate function
ProductOverview
import React from 'react';
import {FlatList, Text} from 'react-native';
import {useSelector} from 'react-redux';
import ProductItem from '../../components/shop/ProductItem';
import { withNavigation, navigate } from 'react-navigation';
const ProductOverviewScreen = (props) => {
const products = useSelector(state => state.products.availableProducts);
return (
<FlatList
data={products}
keyExtractor={item => item.id}
renderItem={itemData => (
<ProductItem
image={itemData.item.imageUrl}
title={itemData.item.title}
price={itemData.item.price}
onViewDetail={()=> {
props.navigation.navigate('ProductDetail')
}}
onAddToCart={() => {}}
/>
)}
/>
);
};
ProductOverviewScreen.navigationOptions = {
title: 'All Products',
color: 'white',
headerTitleStyle: {
color: 'white',
},
};
export default ProductOverviewScreen;
the doc of react-navigation is not telling me much.
Thanks in advance
I am trying to create a drawer navigator, I believe I am doing everything correct but I am getting this error when I try to open the drawer undefined is not an object (evaluating '_this2.props.navigation.navigate'). I did some console logs and found that this.props is empty for every class, including the class in App.js, even after I register the screens. Can someone please help or see if this is an actual bug?
Thanks in advance
How to reproduce
App.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
import Map from './screen'
import Home1 from './home';
// You can import from local files
import AssetExample from './components/AssetExample';
import Nav from './nav';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { createDrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
console.log(this.props);
return (
<View style={styles.container}>
<Home1 {...this.props} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
backgroundColor: '#FFF',
},
innerContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
header: { padding: 15, paddingTop: 22 },
});
home.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
import Map from './screen'
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { DrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
export default class Home1 extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
static navigationOptions = {
drawerLabel: 'Home'
};
render() {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<View style={styles.header}>
<TouchableOpacity
onPress={() => {
console.log(this.props);
console.log(this.props.navigation);
this.props.navigation.navigate('DrawerToggle');}}>
<Icon name="md-menu" size={30} />
</TouchableOpacity>
</View>
<Text> 'hi' </Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
backgroundColor: '#FFF',
},
innerContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
header: { padding: 15, paddingTop: 22 },
});
screen.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { DrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
export default class Map extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
static navigationOptions = {
drawerLabel: 'Map'
};
render() {
return (
<View>
<StatusBar barStyle="dark-content" />
<View style={styles.header}>
<TouchableOpacity
onPress={() => {
console.log(this.props);
console.log(this.props.navigation);
this.props.navigation.navigate('DrawerToggle');}}>
<Icon name="md-menu" size={30} />
</TouchableOpacity>
<Text> 'hello' </Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
backgroundColor: '#FFF',
},
innerContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
header: { padding: 15, paddingTop: 22 },
});
nav.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
import Map from './screen'
import Home1 from './home';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { createDrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
const Nav = createDrawerNavigator({
Home: {
screen: Home1
},
Map: {
screen: Map
},
});
export default Nav;
Your Environment
"react-native-paper": "2.1.3",
"react-navigation": "2.18.2"
Running code online here https://snack.expo.io/
navigation.navigate('DrawerToggle') was removed in v2.
You can use
this.props.navigation.openDrawer();
this.props.navigation.closeDrawer();
to open and close the drawer respectively.
Please refer to https://reactnavigation.org/docs/en/drawer-based-navigation.html
I am an Android developer who works with Android Studio most.
I started with my first react-native project for iOS and I want to know how is it possible to have one screen with a button that when the user clicks takes him to another screen (or activity in an android way) which has a hello message.
I would be really obliged to anyone that can help because I am really new to React and React-Native.
I have tried the following code but I get the following error.
My code is the following:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import { createStackNavigator } from 'react-navigation';
import Settings from './Settings';
import Home from './Home';
const AppNavigator = createStackNavigator({
HomeScreen: { screen: Home },
SettingScreen: { screen: Settings },
});
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Image style={styles.image} source={require('./assets/adc.png')} />
<Text style={styles.adc}>Aratos Disaster Control</Text>
<Button title="Settings" onPress = {() => this.props.navigation.navigate('SettingScreen')} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
adc:{
fontWeight: 'bold',
marginTop: 20
},
image:{
width: 80,
height: 100
}
});
// Home.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
export class Home extends Component {
render() {
return (
<View>
<Text>This is the home screen</Text>
<Button title="Settings" onPress={() => this.props.navigation.navigate('SettingScreen')} />
</View>
)
}
}
export default Home
// Settings.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
export class Settings extends Component {
render() {
return (
<View>
<Text>This is the Settings screen</Text>
</View>
)
}
};
export default Settings;
For navigate between pages, you can use React Navigation or react-native-router-flux or other packages. You have to define the structure of your navigation and then navigate to each page using this packages. Read guides for more information.
I'm trying to add a tabbed navigation to a React Native app, also using expo if that matters, and whenever I do this I get a big chunk of white at the top of the screen. I'm not seeing what's causing this though, the status bar background shouldn't be pushing it down and as far as I can tell changing the height style of my navigation or main view doesn't do anything.
This looks like:
The complete source to recreate this is:
// utils/colors.js
export const white = '#fff'
export const orange = '#f26f28'
// App.js
import React, { Component } from 'react'
import { StyleSheet, View, StatusBar, Dimensions } from 'react-native'
import {
createMaterialTopTabNavigator,
createStackNavigator
} from 'react-navigation'
import { Constants } from 'expo'
import List from './components/List'
import Add from './components/Add'
import { orange, white } from './utils/colors'
function StatusBarBackground ({ backgroundColor, ...props }) {
return (
<View style={{ backgroundColor, height: Constants.statusBarHeight }}>
<StatusBar translucent backgroundColor={backgroundColor} {...props} />
</View>
)
}
const Tabs = createMaterialTopTabNavigator({
List: {
screen: List,
navigationOptions: {
tabBarLabel: 'List',
},
},
Add: {
screen: Add,
navigationOptions: {
tabBarLabel: 'Add',
},
},
}, {
navigationOptions: {
header: null
},
tabBarOptions: {
activeTintColor: white,
style: {
height: 56,
backgroundColor: orange,
shadowColor: 'rgba(0, 0, 0, 0.24)',
shadowOffset: {
width: 0,
height: 3
},
shadowRadius: 6,
shadowOpacity: 1
}
}
})
const MainNavigator = createStackNavigator({
Home: {
screen: Tabs,
},
})
export default class App extends Component {
render() {
return (
<View style={{flex: 1}}>
<StatusBarBackground backgroundColor={orange} barStyle="light-content" />
<MainNavigator />
</View>
)
}
}
The Add and List components are just a view with a text, both look similar to this:
import React, { Component } from 'react'
import { View, Text } from 'react-native'
class Add extends Component {
render() {
return (
<View>
<Text style={{fontSize: 20}}>Add</Text>
</View>
)
}
}
export default Add
You are adding Your Tab Navigator inside Stack Navigator, That is why that white header is showing from Stack Navigator.
1) If You want to add header then style your header like below
const MainNavigator = createStackNavigator({
Home: {
screen: Tabs,
},
},{
navigationOptions:{
headerStyle : {
backgroundColor:'#243346'
},
headerTintColor:"#fff"
},
})
2) If you want to remove header then you can either remove your Tab Navigator from Stack Navigator or add headerMode:'none' inside navigationOprions object.