React Native and Drawer : undefined is not an object navigator - react-native

I want to set up a sidebar menu with Drawer (Native Base).
I have a App.js :
export default class ReactProject extends Component {
renderScene (route, navigator) {
return <route.component navigator={navigator} />
}
render() {
return (
<Navigator
style={styles.container}
renderScene={this.renderScene.bind(this)}
initialRoute={{component: Home}}
/>
);
}
}
A Home.js with the drawer :
export default class Home extends Component {
render() {
return (
<Drawer
ref={(ref) => { this._drawer = ref; }}
content={<SideBar />} navigator={this.props.navigator}>
<Container>
</Container>
</Drawer>
);
}
}
And sidebar.js which is loaded into the drawer :
export default class SideBar extends Component {
constructor(props) {
super(props);
}
redirect(routeName){
this.props.navigator.push({
component: routeName
});
}
render() {
return (
<Content style={styles.sidebar}>
<ListItem button >
<Text>Home</Text>
</ListItem>
<ListItem button >
<Text>Test</Text>
</ListItem>
<ListItem button onPress={this.redirect.bind('Blank')}>
<Text>Blank Page</Text>
</ListItem>
</Content>
);
}
}
But when I click i have this error:
Undefined is not an object (evaluating 'this.props.navigator.push')
I do not have this problem when the button is in the page but only in the sidebar.js
Could someone help me?
thank you,
Thomas.

I think you have to change little bit code of your Home.js as per mentioned below:
render() {
return (
<Drawer
ref={(ref) => { this._drawer = ref; }}
content={<SideBar navigator={this.props.navigator} />}
<Container>
</Container>
</Drawer>
);
And add this lines of code in your sidebar.js file:
static propTypes = {
navigator: React.PropTypes.object,
}

Related

React Native - Get value from component - onPress

I'm trying to get a value from a component that I have pressed but I could not pass it.
My Welcome class is using Menu component while this component has 4 MenuItem components.
Where it would be my problem? I couldn't get itemOnPress value into Welcome screen.
Welcome:
class Welcome extends React.Component {
menuItemOnPress = (item) => {
console.log('ITEM', item);
};
render() {
return (
<Modal animationType={'fade'}
transparent={true}
visible={this.state.modalVisible}>
<View style={styles.modal}>
<Menu itemOnPress={(item) => this.menuItemOnPress(item)}/>
</View>
</Modal>
);
}
Menu:
class Menu extends React.Component {
render() {
const {closeOnPress, itemOnPress} = this.props;
return (
<SafeAreaView style={styles.container}>
<MenuItem titleText={'XYZ'} onPress={itemOnPress(0)}/>
<MenuItem titleText={'XYZ'} onPress={itemOnPress(1)}/>
</SafeAreaView>
);
}
Switch your Menu component onPress functions to arrow function
class Menu extends React.Component {
render() {
const {closeOnPress, itemOnPress} = this.props;
return (
<SafeAreaView style={styles.container}>
<MenuItem titleText={'XYZ'} onPress={() => itemOnPress(0)}/>
<MenuItem titleText={'XYZ'} onPress={() => itemOnPress(1)}/>
</SafeAreaView>
);
}

Access to this.props.navigation on Header Component

I have an ApplicationHeader Component and I want to navigate to a specific screen on touch, but I'm getting
undefined is not an object (evaluating this.props.navigation.navigate)
App.js
render() {
return (
<SafeAreaView forceInset={{ bottom: 'never' }} style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<Provider store={store}>
<ApplicationHeader navigation={this.props.navigation} />
<AppNavigator />
</Provider>
</SafeAreaView>
);
}
ApplicationHeader.js
class ApplicationHeader extends Component {
constructor(props) {
super(props)
}
openWishlist() {
this.props.navigation.navigate('Wishlist')
}
render() {
const { isLogged } = this.props;
return (
<View style={AppStyle.header}>
<TouchableOpacity onPress={() => this.openWishlist()}>
{!isLogged && (<Image source={imgWishList} style={AppStyle.headerWishlist} />)}
{isLogged && (<Image source={imgWishListLogged} style={AppStyle.headerWishlist} />)}
</TouchableOpacity>
</View>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ApplicationHeader);
It seems like that your HeaderComponent is might not be in Navigation Stack.
In that case, you can try the following solution:
First import withNavigation in your file like
import { withNavigation } from 'react-navigation';
After that change your component export to
export default connect(
mapStateToProps,
mapDispatchToProps
)(withNavigation(ApplicationHeader));
So you will get the access to navigation pros in this component.
Also your ApplicationHeader can move to inner container components. It shouldn't have to be in App.js to use the navigation props.
Hope this will help you.

React Native can't find variable: navigate

I am doing stack navigation but I can't seem to be able to navigate I will get this error "Can't find variable: navigate" Here is the screenshot of my android emulator
This is my App class(main)
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Header/>
<AppNavigator/>
</View>
);
}
}
const AppNavigator = StackNavigator({
Cluster1: {
screen: Cluster1,
},
Play: {
screen: Play,
},
});
This is my Cluster1 class
export default class Cluster1 extends Component{
render(){
return(
<View>
<SectionList
renderSectionHeader={({ section }) => {
return (<SectionHeader section={section} />);
}}
sections={ClusterData}
keyExtractor={(item, index) => item.name}
>
</SectionList>
</View>
);
}
}
class SectionHeader extends Component {
render() {
return (
<View style={styles.header}>
<Text style={styles.headertext}>
{this.props.section.title}
</Text>
<TouchableOpacity onPress={() => { navigate("Play");}}>
<Text style ={styles.Play}>Play
</Text>
</TouchableOpacity>
</View>
);
}
}
navigation object only exist in the screen component. (not exist in the nested components). you can pass it into the nested component using props
export default class Cluster1 extends Component{
render(){
return(
<View>
<SectionList
renderSectionHeader={({ section }) => {
return (<SectionHeader navigation={this.props.navigation} section={section} />);
}}
sections={ClusterData}
keyExtractor={(item, index) => item.name}
>
</SectionList>
</View>
);
}
}
class SectionHeader extends Component {
render() {
return (
<View style={styles.header}>
<Text style={styles.headertext}>
{this.props.section.title}
</Text>
<TouchableOpacity onPress={() => { this.props.navigation.navigate("Play");}}>
<Text style ={styles.Play}>Play
</Text>
</TouchableOpacity>
</View>
);
}
}
Include on your SectionHeader the this.props.navigation something like this:
<SectionHeader navigation={this.props.navigation}/>
because the props.navigation are by default on your parent component
and on SectionHeader component you will access to navition like:
..
goToSignUp() {
this.props.navigation.navigate('SignUp');
}
..
For me also was confusing before. Cheers!
You can use this rather than navigate :
this.props.navigation.navigate('Play')
Hope this is helpful.

Radio Buttons are not working on ios

I am trying to use Native-Base radio buttons. I've added some additional code to it for making radio buttons work. While it's still not working. Here is the code:
import React, { Component } from 'react';
import { Container, Header, Content, ListItem, Text, Radio, Right } from 'native-base';
export default class RadioButtonExample extends Component {
constructor() {
super();
this.state = {
itemSelected: 'itemOne',
}
}
render() {
return (
<Container>
<Header />
<Content>
<ListItem>
<Text>Daily Stand Up</Text>
<Right>
<Radio onPress={() => this.setState({ itemSelected: 'itemOne' })}
selected={this.state.itemSelected == 'itemOne'}
/>
</Right>
</ListItem>
<ListItem>
<Text>Discussion with Client</Text>
<Right>
<Radio onPress={() => this.setState({ itemSelected: 'itemTwo' })}
selected={this.state.itemSelected == 'itemTwo' }
/>
</Right>
</ListItem>
</Content>
</Container>
);
}
}
How can this code be fixed? What's wrong?
Handle the onPress event in the ListItem
import React, { Component } from "react";
import { Container, Header, Content, ListItem, Text, Radio, Right } from "native-base";
export default class RadioButtonExample extends Component {
constructor() {
super();
this.state = {
itemSelected: "itemOne",
};
}
render() {
return (
<Container>
<Header />
<Content>
<ListItem onPress={() => this.setState({ itemSelected: "itemOne" })}>
<Text>Daily Stand Up</Text>
<Right>
<Radio selected={this.state.itemSelected == "itemOne"} />
</Right>
</ListItem>
<ListItem onPress={() => this.setState({ itemSelected: "itemTwo" })}>
<Text>Discussion with Client</Text>
<Right>
<Radio selected={this.state.itemSelected == "itemTwo"} />
</Right>
</ListItem>
</Content>
</Container>
);
}
}

undefined is not an object(evaluating this.props.navigator.push)

I have two page i.e sign in page and a payment page.
I am trying to navigate to payment page on tap on SignIn button, but i am getting error undefined is not an object(evaluating this.props.navigator.push)
The code is as below:
import React, {
StyleSheet,
Text,
View,
TextInput,
Component,
Alert,
Navigator
} from 'react-native';
var Button = require('react-native-button');
import Payments from '../payments'
class Signin extends Component{
onSubmitPressed(){
this.props.navigator.push({
title: 'secure Page',
component: <Payments/>
});
};
render() {
return(
<View style={styles.container}>
<View style={styles.Inputview}>
<TextInput id='user' style={styles.input}
placeholder={'Username'}
/>
<TextInput id='Password' secureTextEntry={true}
placeholder={'Password'}
onChangeText={password => this.setState({password})}
/>
</View>
<View >
<Button style={styles.Register}
onPress={(this.onSubmitPressed)}>
Sign In
</Button>
</View>
</View>
)
}
}
export default Signin
If any one let me know how to solve this issue??
You need to set up your Navigator and initial route as the entry point as opposed to a regular component. Try something like this:
(Also set up a working example here)
https://rnplay.org/apps/iKx2_g
class App extends Component {
renderScene (route, navigator) {
return <route.component navigator={navigator} />
}
render() {
return (
<Navigator
style={styles.container}
renderScene={this.renderScene.bind(this)}
initialRoute={{component: SignIn}}
/>
);
}
}
class SignIn extends Component {
_navigate () {
this.props.navigator.push({
component: Payments
})
}
render () {
return (
<View>
<Text>Hello from SignIn</Text>
<Button onPress={this._navigate.bind(this)} />
</View>
)
}
}
class Payments extends Component {
render () {
return (
<Text>Hello from Payments</Text>
)
}
}
First you need to bind the this to the function onSubmitPressed. And make sure that you have passed navigator object to this component on the renderScene function of the navigator.
// binding this to onSubmitPressed
<Button style={styles.Register}
onPress={this.onSubmitPressed.bind(this)}
>
Sign In
</Button>
// binding this to on SubmitPressed using arrow function
<Button style={styles.Register}
onPress={() => this.onSubmitPressed()}
>
Sign In
</Button>