How to implement React native DrawerLayout with ToolbarAndroid? - react-native

I am trying to implement navigation drawer on click of menu icon in toolbar, i am trying this from many days but i could not find any good resource online,I have followed some stack overflow answer and implemented this till now:
MyToolbar.js
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text
} from 'react-native';
var ToolbarAndroid = require('ToolbarAndroid');
export default class MyToolbar extends Component {
render() {
// var navigator = this.props.navigator;
return (
<ToolbarAndroid
title={this.props.title}
navIcon={require('./ic_menu.png')}
style = {styles.toolbar}
titleColor={'white'}
onIconClicked={this.props.sidebarRef}/>
);
}
}
const styles = StyleSheet.create({
toolbar: {
height: 56,
backgroundColor: '#08AE9E',
width: 370,
alignItems: 'center'
}
});
openDrawerFromToolbar.js
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
DrawerLayoutAndroid,
ScrollView,
} from 'react-native';
var ToolbarAndroid = require('ToolbarAndroid');
var MyToolbar = require('./MyToolbar');
export default class OpenDrawerFromToolbar extends Component {
render() {
var navigationView = (
<ScrollView>
<View style = {{height:100, backgroundColor:'blue', justifyContent:'center'}}>
<Text style = {{height:25, color:'white', fontSize:25, marginLeft:20}}>Welcome To ReactNative</Text>
</View>
// <ListView></ListView>
//render your list items
</ScrollView>
);
return (
<DrawerLayoutAndroid
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}
ref={'DRAWER'}>
<MyToolbar style={styles.toolbar}
title={'Calendar'}
sidebarRef={()=>this._setDrawer()}/>
</DrawerLayoutAndroid>
);
}
_setDrawer() {
this.refs['DRAWER'].openDrawer();
}
}
const styles = StyleSheet.create({
//your own style implementation
});
index.android.js
import React, { Component } from 'react';
import {
AppRegistry
} from 'react-native';
var OpenDrawerFromToolbar = require('./components/OpenDrawerFromToolbar');
class NewsTrack extends Component {
render() {
return (
<OpenDrawerFromToolbar
/>
);
}
}
AppRegistry.registerComponent('NewsTrack', () => NewsTrack);
Initially clicking on toolbar was not doing any action and navigation drawer was not opening now I'm getting blank screen. what am i missing in the code?
Edit : I have updated the code and now i am facing this error: "Element type is invalid: expected a string(for built-in components)or a class/function (for composite components) but got: object.
I have checked other such question they say some import or export is wrong i am not able to find out which in my case is wrong, can someone please help?

You can use Drawer provided by native base . It comes with toolbar functionality and very easy to use. I am using it in one of my projects.
https://docs.nativebase.io/Components.html#Drawer

Related

NativeBase: Button does not work, but ReactNative's Button does

Experiencing a strange issue in my React Native project for Android.
Using React-Navigation, I have a component with a button inside. This button should navigate to a new screen.
Thing is, the built-in button of React Native works like a charm, while the button of Native Base does not. I am completely confused, even more because I use this Native Base Button in another location, too. And there it works fine.
What is going on here?
Here, you see the application works with the built-in React Native button:
On the opposite, using the button of Native Base, it not only does not work, even styles are not applied.
Here is the code with the React Native button:
import React from "react";
import { Button, View, Text, StyleSheet } from "react-native";
import { withNavigation } from "react-navigation";
type Props = { navigation: any };
const ButtonTestScreen: React.FC<Props> = ({ navigation }) => {
return (
<View>
<Button
title="Hi i am a button"
onPress={() => navigation.navigate("Details")}
></Button>
</View>
);
};
export default withNavigation(ButtonTestScreen);
And the code with Native Base button:
import React from "react";
import { Button, View, Text, StyleSheet } from "react-native";
import { withNavigation } from "react-navigation";
import ButtonNavigate from "../../components/atoms/ButtonNavigate/ButtonNavigate";
type Props = { navigation: any };
const ButtonTestScreen: React.FC<Props> = ({ navigation }) => {
return (
<View>
<ButtonNavigate
title="Hi i am a button"
navigateTo="Details"
></ButtonNavigate>
</View>
);
};
const styles = StyleSheet.create({
button_style: {
backgroundColor: "red"
},
text_style: {
color: "#000",
fontSize: 30
}
});
export default withNavigation(ButtonTestScreen);
And the respective ButtonNavigate component itself:
import React from "react";
import { StyleSheet } from "react-native";
import { withNavigation } from "react-navigation";
import { Button, Text } from "native-base";
type Props = {
title: string,
navigateTo: string,
navigation: any
};
const ButtonNavigate: React.FC<Props> = ({ title, navigateTo, navigation }) => {
return (
<Button
rounded
transparent
style={styles.button_style}
onPress={() => navigation.navigate(navigateTo)}
>
<Text style={styles.text_style}>{title}</Text>
</Button>
);
};
const styles = StyleSheet.create({
button_style: {
backgroundColor: "red"
},
text_style: {
color: "#151414"
}
});
export default withNavigation(ButtonNavigate);
I have just tested you code in expo.snack but without navigation and its ok,
see it here
You can test in your app to remove navigation and go step by step until you find the bug.
Folks, reason for this strange behavior is the "rounded" property of Native Base's button. In my application, somehow it causes the button to become non-clickable.
Maybe contributors of Native Base know what to do with this problem, so if you read this, maybe you have an idea.
Solution for my now was simply removing "rounded".
Native Base: 2.13.8
React-Navigation: 4.0.10
In my case it was the "top" in the container property of the button causing this issue. Removed it and adding "marginBottom" to the container above it solved the issue

Trouble passing down this.props.navigation to child components

I am having a little trouble accessing this.props.navigation.navigate in child pages within ViewPager. I have a page where there's a button called "Details" and upon clicking the button it should open up a new separate view (like a new Intent Activity).
Structure is:
Login page -> tap on "login" button -> opens MainPage having a custom CustomBottomNavigationBar with ViewPager component which takes {Object} of 5 different pages and renders them like:
In the root App.js I've already defined this configuration:
// App.js
import MainPage from './views/mainpage';
import PageOne from './views/pageoneview';
import PageTwo from './views/pagetwoview';
import PageOneDetailView from './views/PageOneDetailView';
const MainNavigator = createStackNavigator({
Home: {screen: MainPage},
PageOne: {screen: PageOne},
PageTwo: {screen: PageTwo},
PageOneDetailView: {screen: PageOneDetailView}
},
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
// mainpage.js
import React, { Component } from 'react';
import {
StyleSheet,
Image,
View,
TouchableOpacity,
ToastAndroid
} from 'react-native';
import PageOne from './homepages/pageoneview';
import PageTwo from './homepages/pagetwoview';
import CustomBottomNavigationBar from './../components/CustomBottomNavigationBar';
export default MainPage extends Component {
constructor(props) {
super(props);
}
screens = () => {
return {
p1: {page: <PageOne/>},
p2: {page: <PageTwo/>}
}
}
render() {
return (
<CustomBottomNavigationBar
screensets={this.screens()}
/>
);
}
}
Now in PageOne.js there is a button called "Details" and on tapping, it must open a new PageOneDetail.js
// pageoneview.js
import React, { Component } from 'react';
import {
StyleSheet,
Image,
View,
TouchableOpacity,
ToastAndroid
} from 'react-native';
import PageOneDetail from './homepages/PageOneDetailView';
export default PageOne extends Component {
constructor(props) {
super(props);
}
OpenView = (navigateObject, whichScreen) => {
navigateObject(whichScreen);
}
render() {
const {navigate} = this.props.navigation;
return (
<View style={{ flex: 1, alignSelf: 'flex-end' }}>
<TouchableOpacity onPress={() => this.OpenView(navigate, 'PageOneDetailView')}>
<Text> Details </Text>
</TouchableOpacity>
</View>
);
}
}
The error I get when I land on the MainPage is: undefined is not an object this.props.navigation.navigate when mainpage.js tries to load pageoneview.js
Please help me understanding how to fix this issue which I have been facing whole day.
Thanks.
The navigation prop is only accessible to screens, not children of those screens. You can pass down the navigation from the parent or use withNavigation HOC or useNavigation hook from react-navigation-hooks to access it everywhere.

Can not use global styles in styled-components

I am trying to setup global styles in react-native.
I have imported
import {injectGlobal} from 'styled-components';
and have
class XoxoContainer extends Component {
render() {
return <Xoxo {...this.props} />
}
}
injectGlobal`
font-family: '20'
`;
But I keep getting styledComponents.injectGlobals is not a function. in the console.
That function is not part of the library on react-native according to this Github issue. That's why it keeps saying that it's not a function, because it can't find it.
create a styles.js file like this:
import React, {Component} from 'react';
import {
Platform,
StyleSheet
} from 'react-native';
export const styles = StyleSheet.create({
view_flex_one_white: {
flex: 1,
backgroundColor: white
}});
and use this anywhere in your app with import
import {styles} from "...link to file/styles";
render(){
return(
<View style={styles.view_flex_one_white}>
</View>
)
}
Create a js file with this pattern:
'use strict';
var React = require('react-native');
var myStyle = React.StyleSheet.create({
style1: { },
style2: { }
)}
module.exports = myStyle;
your component js use require to use that style sheet
var customStyle = require('../the/path/to/commonStyleSheet');
Use now like this:
<View style = {customStyle .style1} />

Navigation in React Router v4 Native Not Changing Scenes

I'm using React Router for a React Native app. Not sure what I'm missing here but I install react-router-native and require the history package, and setup a couple methods that just push a new route onto the stack but nothing happens. I console.log('clicked'); to check that it's firing and it is so not sure what's wrong.
import React, { Component } from 'react';
import { View } from 'react-native';
import Splash from './Splash';
import createHistory from 'history/createMemoryHistory';
const history = createHistory();
class SplashContainer extends Component {
goToLogin = () => {
history.push('/Login');
}
goToRegister = () => {
history.push('/SignUp');
}
render () {
console.log(history)
return (
<Splash
goToLogin={this.goToLogin}
goToRegister={this.goToRegister}
/>
);
}
}
export default SplashContainer;
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { Button } from 'native-base';
import { Link } from 'react-router-native';
import PropTypes from 'prop-types';
const Splash = (props) => {
console.log(props)
return (
<View style={styles.container}>
<Button light block onPress={props.goToLogin}>
<Text>Login</Text>
</Button>
<Button dark block bordered style={{marginTop: 10}} onPress={props.goToRegister}>
<Text>Register</Text>
</Button>
</View>
);
}
Splash.propTypes = {
goToLogin: PropTypes.func.isRequired,
goToRegister: PropTypes.func.isRequired
}
export default Splash;
I don't know your Router config, but your methods should be:
goToLogin = () => {
const { history } = this.props
history.push('/Login');
}
history will passed down via props of component inside Router's stack.

react native - Check the render method of Navigator

I am new at react native and trying to understand the use of navigation there....
found this example code:
import React, { Component } from 'react';
import { AppRegistry, Text, Navigator } from 'react-native';
import Apple from './app';
import Orange from './app'
class AwesomeProject extends Component {
render() {
return (
<Navigator
initialRoute={{screen: 'Apple'}}
renderScene={(route, nav) => {return this.renderScene(route, nav)}}
/>
)
}
renderScene(route,nav) {
switch (route.screen) {
case "Apple":
return <Apple navigator={nav} />
case "Orange":
return <Orange navigator={nav} />
}
}
}
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
Also created:
Apple.js
import React, { Component } from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
export default class Apple extends Component {
render() {
return (
<View>
<Text>Apple</Text>
<TouchableHighlight onPress={this.goOrange.bind(this)}>
<Text>Go to Orange</Text>
</TouchableHighlight>
</View>
)
}
goOrange() {
console.log("go to orange");
this.props.navigator.push({ screen: 'Orange' });
}
}
But I am getting this error for some reason...
why?
this is the error message I am getting in the emulator
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of `Navigator`.
instantiateReactComponent
index.android.bundle?platform=android&dev=true&hot=true&minify=false:23290:16
updateChildren
index.android.bundle?platform=android&dev=true&hot=true&minify=false:23171:58
_reconcilerUpdateChildren
index.android.bundle?platform=android&dev=true&hot=true&minify=false:22945:44
_updateChildren
index.android.bundle?platform=android&dev=true&hot=true&minify=false:23015:54
updateChildren