Reputation: 2197
I have a simple component that toggles between two sets of items - Hours & Happy Hours. The component works fine on iOS, but causes my app to crash (silently) on Android.
I have a working example here: https://snack.expo.io/Sk92sIEmf. And here is the code used, for reference:
import React, { Component } from 'react';
import { Dimensions, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
const { width } = Dimensions.get('window');
export default class App extends Component {
constructor(props){
super(props);
this.state = {
showAnother: true,
oneThingActive: false,
anotherActive: true,
};
}
handlePress = () => {
const { anotherActive, oneThingActive } = this.state
return this.setState({ anotherActive: !anotherActive, oneThingActive: !oneThingActive });
}
render() {
const { showAnother, oneThingActive, anotherActive } = this.state
return (
<View style={s.container}>
<View style={s.sRow}>
<TouchableOpacity style={s.titleCont} activeOpacity='1' onPress={this.handlePress}>
<Text style={[s.text, s.title, !oneThingActive && s.inactive]}>ONE THING</Text>
</TouchableOpacity>
{ showAnother &&
<Text style={[s.text, s.title]}>|</Text>
}
{ showAnother &&
<TouchableOpacity style={s.titleCont} activeOpacity='1' onPress={this.handlePress}>
<Text style={[s.text, s.title, !anotherActive && s.inactive]}>ANOTHER</Text>
</TouchableOpacity>
}
</View>
{ oneThingActive &&
<View style={s.row}>
<Text style={[s.text, s.day]}>testing..</Text>
</View>
}
{ anotherActive &&
<View style={s.row}>
<Text style={[s.text, s.day]}>123..</Text>
</View>
}
</View>
)
}
}
const s = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
marginHorizontal: 35,
marginVertical: 5,
borderColor: '#D4D4D4',
borderTopWidth: 1,
borderBottomWidth: 1,
},
titleCont: {
alignSelf: 'flex-start',
},
title: {
color: '#232323',
fontSize: 14,
alignSelf: 'flex-start',
marginHorizontal: 5,
},
text: {
color: '#232323',
fontSize: 13,
},
inactive: {
color: '#95989A',
},
row: {
display: 'flex',
flexDirection: 'row',
},
sRow: {
display: 'flex',
flexDirection: 'row',
width: width,
alignItems: 'center',
justifyContent: 'center',
paddingBottom: 5,
},
})
As stated earlier, I don't really get an error when this crashes. At one point, I saw something to the effect of "attempted to assign read only property," but I am no longer seeing that error message. Any help or a point in the right direction would be greatly appreciated.
Thanks !
Edit:
Updated with a simplified example. It seems the crash is coming from the conditional render (this.state.oneThingActive && ...
), a pattern I frequently use and have not run into any issues like this with.
The best way to reproduce is to visit this link: https://snack.expo.io/Sk92sIEmf, which has an IDE setup for React Native apps. You should find that the toggle works fine when the Platform is iOS, but once a state change is attempted in the Android version the app crashes.
Edit 2:
Seems the problem was due to the usage of TouchableOpacity
.... I noticed the Android app was crashing from a console.log("...")
, so I tried swapping in TouchableHighlight
and got it to work.
Going to investigate this more over the coming days, but would love to hear input if anyone has some.
Answer
This all seems a bit silly now, but my error was getting caused by activeOpacity='1'
. I was passing in 1 as a String
instead of as a Number
. activeOpacity={1}
does the trick. Do yourself a favor (unlike me in this instance) and use a linter.
Upvotes: 1
Views: 3354
Reputation: 11384
I just encountered the same thing. In my case it was an issue of it not liking quotes in my style. Not sure about your case, but in my case when I added a
style={{marginRight: "20px"}}
by mistake it crashed. I should have had
style={{marginRight: 20}}
instead. Even just having
style={{marginRight: '20'}}
or
{{marginRight: "20"}}
causes it to crash.
I notice that you have activeOpacity='1'
in your code and am wondering if you remove the quotes around the 1
whether it solve your problem.
Upvotes: 4
Reputation: 1348
This looks like a problem with the fact that class methods are not automatically bound to the instance. Add these to your constructor:
this.hoursPressed = this.hoursPressed.bind(this);
this.happyHoursPressed = this.happyHoursPressed.bind(this);
This is a common problem with using ES6 classes with React.
Upvotes: -1