--- delete everything above this line before submitting your issue ---
I used TouchableHighlight, I am using it for toggling Boolean value. But on render() TouchableHighlight is automatically getting pressed, and due to infinite loop my app is getting crashed. Flow of my program is as follows.
I am applying timeout in componentWillMount() and fetching Data in componentDidMount() after 3 seconds I am displaying page. I am getting data correctly and all data is showing up till I am not adding onPress property on TouchableHighlight. I am providing my complete program in code snippet section.
/**
* ASAP app using react-native
* Author:-Gaurav Bhusare
*
*/
import React, {
Component
} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableHighlight,
TextInput,
Image,
Navigator,
AsyncStorage,
Picker,
Item,
ListView,
TabBarIOS,
ScrollView
} from 'react-native';
import Tabs from 'react-native-tabs';
//import Payments from './Payments'
import Global from './Global';
//import Details from './Details'
import Dimensions from 'Dimensions';
const width1 = Dimensions.get('window').width;
const height1 = Dimensions.get('window').height;
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) =>r1 !== r2
});
export default class OwnerHome extends Component {
constructor(props) {
super(props);
this.state = {
payments: [],
timePassed: false,
//dataSource2: ds.cloneWithRows([]),
unitSelected: '',
units: [],
unitDetails:{},
status: "Empty",
showOwn:false
}
}
async getUnitDetails(id) {
//alert(id)
this.setState({unitSelected: id})
var DEMO_TOKEN = await AsyncStorage.getItem(Global.STORAGE_KEY);
fetch(Global.URL + "api/units/"+this.state.unitSelected, {
method: 'get',
dataType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': DEMO_TOKEN
},
}).then((response) =>{
//alert(JSON.stringify(response))
return response.json() //<<This is the problem
}).then(function(data) {
//alert(JSON.stringify(data,null,4))
/*const tempNames = [];
for (var i = 0; i<data.length; i++) {
tempNames.push(data[i]);
}
this.setState({
payments: tempNames,
dataSource2: ds.cloneWithRows(data)
});
*/
this.setState({
unitDetails:data,
timePassed: true
});
}.bind(this)).catch(function(err) {
alert("Error is" + err)
console.log(err);
})
.done();
}
async startingPage() {
//alert(this.state.unitSelected)
//this.setState({unitSelected: id})
var DEMO_TOKEN = await AsyncStorage.getItem(Global.STORAGE_KEY);
fetch(Global.URL + "api/units/"+this.state.unitSelected, {
method: 'get',
dataType: 'json',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': DEMO_TOKEN
},
}).then((response) =>{
//alert(JSON.stringify(response))
return response.json() //<<This is the problem
}).then(function(data) {
alert(JSON.stringify(data,null,4))
/*const tempNames = [];
for (var i = 0; i<data.length; i++) {
tempNames.push(data[i]);
}
this.setState({
payments: tempNames,
dataSource2: ds.cloneWithRows(data)
});
*/
this.setState({
unitDetails:data,
timePassed: true
});
if(data.status==1){
this.setState({status:"Empty"})
}
if(data.status==2){
this.setState({status:"Occupied"})
}
if(data.status==1){
this.setState({status:"Rented"})
}
}.bind(this)).catch(function(err) {
//alert("Error is" + err)
console.log(err);
})
.done();
}
componentWillMount() {
setTimeout((function(){
this.setState({timePassed:true})
}).bind(this),3000)
}
componentDidMount() {
this.setState({units:Global.user.unitids})
this.getUnitDetails(Global.user.unitids[0])
}
renderLoadingView() {
return (
<View style={styles.container}>
<Text style={{fontSize: 20}}>
Loading...</Text>
</View>
);
}
showOwner(){
if(this.state.showOwn){
return(
<View>
<Text style={{fontSize: 20,color:'black'}}><Text style={{fontWeight:'bold'}}> Owner:-</Text> {this.state.unitDetails.owner.name}</Text>
<Text style={{fontSize: 20,color:'black'}}><Text style={{fontWeight:'bold'}}> Status:-</Text> {this.state.status}</Text>
</View>
)
}
}
renderScene(route, navigator) {
//alert(JSON.stringify(this.state.payments,null,4))
if (!this.state.timePassed) {
return this.renderLoadingView()
}
return (
<ScrollView>
<View style={styles.strip}>
<Image style={{width: 50, height: 30, padding: 10, top: 5}} source={require( './drawable/drawable/asap.png')} />
<Text style={{fontSize: 20, color: 'white', bottom: 20, left: 60, padding: 10}}>Approvals</Text>
</View>
<View>
<View style={{top: 50}}>
<View>
<Tabs selected={this.state.page} style={styles.tabbar} selectedStyle={styles.tabbarSelected} onSelect={el=>this.setState({page: el.props.name})}>
<Text style={{fontSize: 20}} name="Approvals">Approvals</Text>
<Text style={{fontSize: 20}} name="Payments">Payments</Text>
</Tabs>
</View>
<ScrollView style={{paddingBottom: 70}}>
<Picker selectedValue={this.state.unitSelected}
style={{width:200, left:100,bottom: 10}}
label="Select Unit"
onValueChange={(selectedUnit) => this.getUnitDetails(selectedUnit)}>
{this.state.units.map((s, i) => {
return <Picker.Item key={i} value={s} label={s}/>
})}
</Picker>
<View style={styles.separator} />
<TouchableHighlight style={{flex:1, backgroundColor:'powderblue'}} onPress={this._onPressButtonOwner()}>
<Text style={{fontSize: 20,color:'black'}}>Owner Details</Text>
</TouchableHighlight>
{this.showOwner()}
</ScrollView>
</View>
</View>
</ScrollView>
);
}
_onPressButtonOwner() {
alert("Button")
this.setState({showOwn:!this.state.showOwn})
}
render() {
return (
<Navigator renderScene={this.renderScene.bind(this)} navigator={this.props.navigator} />
);
}
}
const styles = StyleSheet.create({
separator: {
height: 2,
backgroundColor: 'black'
},
strip: {
width: width1,
height: 50,
backgroundColor: 'grey'
},
input: {
height: 50,
flex: 1,
paddingHorizontal: 8,
fontSize: 15,
backgroundColor: '#FFFFFF',
}
})
I should get the view in shoOwner() function after clicking on TouchableHighlight "Owner Details".
You are calling the onPress function in the TouchableHighlight component. onPress={this._onPressButtonOwner()} which is setting state, which is calling render, which in turn is calling the function again ad infinitum. lose the brackets such that you end up with onPress={this._onPressButtonOwner}
@ggordan Great sir, thanks a lot my issue is resolved. Thanks for your help.
I had the same issue as well. I fixed it after reading this comment, but actually tried the following instead because I needed to have parameters passed to my function... and it worked this.onPress={this._onPressButtonOwner.bind(null, parameterOneExample, this.state.parameterTwo}
Most helpful comment
I had the same issue as well. I fixed it after reading this comment, but actually tried the following instead because I needed to have parameters passed to my function... and it worked
this.onPress={this._onPressButtonOwner.bind(null, parameterOneExample, this.state.parameterTwo}