NavigatorIOS problems - react-native

Hi I'm having some trouble using the NavigatorIOS in my app, it gives me the error:'undefined is not an object(evaluating 'this.props.navigator.push').
I tried to see some examples but I can't see the error, can someone help me?
Here is the code:
import React, { Component, PropTypes } from 'react';
import Dimensions from 'Dimensions';
import Menu from './Menu'
import {
AppRegistry,
StyleSheet,
Image,
TouchableHighlight,
NavigatorIOS,
FadeInView,
Text,
View
} from 'react-native';
class Home extends React.Component {
constructor(props, context) {
super(props, context);
this.onForward = this.onForward.bind(this);
}
onForward(Menu){
this.props.navigator.push({
component: Menu,
title: "Menu",
navigationBarHidden: true,
});
}
render() {
return (
<View style={styles.container}>
<Image
style={styles.img}
source={require('./img/scrittaNera.png')}
onLoadStart={(e) => this.setState({loading: true})}
/>
<TouchableHighlight style={styles.button} onPress={() => this.onForward()}>
<Text style={styles.buttonText}>Get Inspired</Text>
</TouchableHighlight>
</View>
);
}
}
Thanks

You need to bind the function to your Component in this case this can be done as follows:
<TouchableHighlight
style={styles.button}
onPress=this.onForward.bind(this)>
....
</TouchableHighlight>
Also you need to make sure your main component is wrapped inside a <NavigatorIOS> component. Such as:
import React, { Component, PropTypes } from 'react';
import { NavigatorIOS, Text } from 'react-native';
export default class NavigatorIOSApp extends Component {
render() {
return (
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
}}
style={{flex: 1}}
/>
);
}
}

Related

How to re-render import component on state change

I have made two component (parent & child) & import the child component containing react-native modal
I have render child component after state change, it renders first time but on second time, it doesn't work.
Parent.js file is as follows:
import react, {Component} from 'react';
import { View, Text, TouchableOpacity} from 'react-native';
import ActionModal from './ActionModal';
export default class Parent extends Component {
constructor(props){
super(props);
this.state = { tabclicked: false }
}
actiontabclicked = () => {
this.setState({ tabclicked: true });
}
render(){
return (
<View>
<TouchableOpacity onPress={() => { this.actiontabclicked()} }>
<Text> MOVE</Text>
</TouchableOpacity>
{ (this.state.tabclicked) ? <ActionModal /> : null }
</View>
)
}
}
ActionModal.js file code
import React, {Component} from 'react';
import {Modal, Text, TouchableHighlight, View, Alert} from 'react-native';
export default class ActionModal extends Component {
constructor(){
super();
this.state = { modalVisible: true }
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{marginTop: 22}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => { this.setModalVisible(!this.state.modalVisible)}}>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
</View>
</View>
</Modal>
</View>
);
}
}
ActionModal opens first time but not second time, I think this is because state becomes true but after close modal it doesn't reset.
How can I achieve that ? Thanks in advance
You're not being so clear with what you want to achieve, if you want to achieve this behaviour of tapping > dismiss > tap again > shows
you should make something like this on your setModalVisible function:
setModalState = () => {
this.setState(prevState => ({
modalVisible: !prevState.modalVisible
})
}
This will change the state opposite to what it was. If you want to have more control maybe you can create two functions setModalOpen and setModalClosed
Maybe you can use props on the child component when onRequestClose is triggered to pass this function to the parent and there you can call setModalClosed, the way you have to do it is to make a callback with the given props (look for passing props to parent in react on the internet, it's quite simple)
Hope I could help

Unable to set event handler in react native navigationOptions headerRight

I'm new to react native. I am trying to setup a event handler to react-navgation. I using navigationOptioins-> headerRight-> icon and trying to set a _BananaButton to handle onPress event. But it is not working. Clicking on icon does not do anything.
The same event handler is working in the TouchableHighlight button but not in the header.
Please suggest.
import React, { Component } from 'react';
import { Alert, Platform, StyleSheet, Button, Text, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback, View, Linking } from 'react-native';
import FruitViewer from './FruitViewer';
import Icon from 'react-native-vector-icons/FontAwesome';
import PropTypes from 'prop-types'; import {
createStackNavigator,
} from 'react-navigation';
export class Touchables extends Component {
_BananaButton() {
const { navigate } = this.props.navigation;
navigate('FruitViewer');
}
static navigationOptions = ({navigation}) => {
console.log(this.props)
//onPress={navigation.state.params.RightHandler}
return {
title: 'Home',
headerStyle: { backgroundColor: 'white' },
headerTitleStyle: { color: 'blue' },
headerRight: (
<Icon
onPress={this._BananaButton}
name='home'
size={25} //onPress={() => alert('This is a button!')}
color="#0000ff" //onPress={() => alert('This is a button!')}
style={{height:25,width:25}}
/>
),
}
}
constructor(props) {
super(props);
this._BananaButton = this._BananaButton.bind(this)
console.log('constructor')
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<TouchableHighlight onPress={this._BananaButton} underlayColor="white" >
<View style={styles.button}>
<Text style={styles.buttonText}>Banana</Text>
</View>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({..})
const App = createStackNavigator({
Touchables: { screen: Touchables },
FruitViewer: { screen: FruitViewer },
});
export default App;
You need to add
componentDidMount() {
this.props.navigation.setParams({ _BananaButton: this._BananaButton });
}
And use it like:
<Icon
onPress={navigation.getParam('_BananaButton')}
Please read react-navigation documentation for this topic Header buttons heandlers

How to setState without using .bind(this) in react-native?

I have no idea How to set state.
Below is my code...
import React from 'react';
import { StyleSheet, Text, View, TouchableHighlight, AsyncStorage, ListView } from 'react-native';
export default class App extends React.Component {
constructor(){
super();
this.state = {
myLeader: 'Joe',
};
}
setMyLeader(name){
this.setState({
myLeader: name
});
}
render() {
return (
<View>
<TouchableHighlight
style={{padding: 30}}
onPress={this.setState(myLeader: 'xxx')}
>
<Text>foo</Text>
</TouchableHighlight>
</View>
);
}
}
error message is this. 'Can't find variable: myLeader'
How to fix this problem?
Inside your onPress function you can:
a) directly set the state
onPress={() => this.setState({ myLeader: 'xxx' })}
b) call your setLeader function
onPress={() => this.setMyLeader('xxx')}

ReactNative navigation

I'm having a great deal of trouble implementing a navigationsystem for my ReactNative app. Here's the index.js:
class Test extends Component {
render() {
const routes = [
{title: 'LoginScreen', index: 0},
{title: 'RegisterScreen', index: 1},
];
return (
<Navigator
initialRoute={routes[0]}
initialRouteStack={routes}
renderScene={(route, navigator) =>
<TouchableHighlight onPress={() => {
navigator.push(routes[1]);
}}>
<Text>Hello {route.title}!</Text>
</TouchableHighlight>
}
style={{padding: 100}}
/>
)
}
}
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
} else {
}
});
At the moment I have simply written a navigation straight off the docs. But I would want it to transition to another screen inside the if statements when checking for a Firebase user. So transitioning to one scene if a user exists and another scene if not.
I find the documentation of this very poor, so I can't even build a basic idea of how to modify this method of transitioning (seems to be endless ways of doing it, sigh..) into working to my situation.
You can definitely use the below example, It hops onto screens by 2 if he found user or hops onto screens by 1.
Assuming user already present
1. index.android.js
import React,{Component} from 'react';
import{
AppRegistry,
StyleSheet,
Text,
ScrollView,
Navigator,
View,
} from 'react-native';
import Navigation from './navigation'
export default class Example extends Component{
constructor(){
super();
this.state={
username: 'ABC',
}
}
render() {
var nextIndex
return (
<Navigator
initialRoute={{ title: 'My Initial Scene', index: 0 }}
renderScene={(route, navigator) =>
<Navigation
title={route.title}
onForward={() => {
if(this.state.username)
nextIndex = route.index + 2 ;
else
nextIndex = route.index + 1 ;
navigator.push({
title: 'Scene ' + nextIndex,
index: nextIndex,
});
}}
onBack={() => {
if (route.index > 0) {
navigator.pop();
}
}}
/>
}
/>
);
}
}
AppRegistry.registerComponent('Example', () => Example);
2. navigation.js
import React,{Component} from 'react';
import{
StyleSheet,
Text,
Navigator,
TouchableHighlight,
View,
} from 'react-native';
export default class Navigation extends Component{
constructor(props) {
super(props)
}
render() {
return (
<View>
<Text>Current Scene: {this.props.title}</Text>
<TouchableHighlight onPress={this.props.onForward}>
<Text>Tap me to load the next scene</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this.props.onBack}>
<Text>Tap me to go back</Text>
</TouchableHighlight>
</View>
)
}
}
This is the working example for RN 0.40.0

React native got blank screen

I'm new to react-native, and I'm trying to use a navigator to switch between different scenes. However, when the simulator runs, instead of printing an error, I just got an empty, blank, white screen that shows nothing expect the remaining battery, the time, and the wifi signal. I checked my code many times and cannot find an error. Can someone help me on this?
This is my index.ios.js file:
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
Navigator
} from 'react-native';
import Chatroom from './Views/Chatroom';
import Chat from './Views/Chat';
class goals extends Component{
render(){
return(
<Navigator
initialRoute={{screen: 'Chatroom'}}
renderScene={(route, nav) => {return this.renderScene(route.screen)}}
/>
)
}
renderScene(route,nav) {
switch (route.screen) {
case 'Chatroom':
return <Chatroom navigator={nav} />
case 'Chat':
return <Chat navigator={nav} />
}
}
}
AppRegistry.registerComponent('goals', () => goals);
This is my Chat.js file:
import React, { Component } from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
export default class Chat extends Component {
render() {
return (
<View>
<Text>This is chat</Text>
<TouchableHighlight onPress={this.gochatroom.bind(this)}>
<Text>Go to chatroom</Text>
</TouchableHighlight>
</View>
)
}
gochatroom() {
this.props.navigator.push({ screen: 'Chatroom' });
}
}
This is my Chatroom.js file:
import React, { Component } from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
export default class Chatroom extends Component {
render() {
return (
<View>
<Text>This is chatroom</Text>
<TouchableHighlight onPress={this.gochat.bind(this)}>
<Text>Go to chat</Text>
</TouchableHighlight>
</View>
)
}
gochat() {
this.props.navigator.push({ screen: 'Chat' });
}
}
You aren't passing the right arguments to renderScene. The following should work better:
renderScene={(route, nav) => this.renderScene(route, nav)}