I've created a small form with two options. Basically I want the user to choose one option and to pass that value in the state "preference" (and further to pass that value in firebase). I'm not sure if my approach with the "If Condition" to choose between options is the correct way because I am a Javascript and React Native beginner.
How would you approach this in terms of code?
export default class ChooseOption extends Component {
state = {
option1: false,
option2: false,
preference: ''
}
chooseFirst = () => {
if (this.state.option1 == false) {
this.setState({ option1: true})
this.setState({ option2: false })
}
}
chooseSecond = () => {
if (this.state.option2 == false) {
this.setState({option2: true})
this.setState({option1: false})
}
}
render() {
return(
<View style={styles.container}>
<Text style={styles.greeting}>Select one option:</Text>
<View style={styles.form}>
<TouchableOpacity
onPress={this.chooseFirst}
style={{flexDirection:'row', alignItems: 'center'}}>
<Icon
name={this.state.option1 ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color= {this.state.option1 ? 'green' : 'gray'}
/>
<Text
style={this.state.option1 ? styles.textOn : styles.textOff}>First Option</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.chooseSecond}
style={{marginTop: 30, flexDirection:'row', alignItems: 'center'}}>
<Icon
name={this.state.option2 ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color= {this.state.option2 ? 'green' : 'gray'}
/>
<Text
style={this.state.option2 ? styles.textOn : styles.textOff}>Second Option</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
greeting: {
marginHorizontal: 30,
marginTop: 307,
fontSize: 30,
lineHeight: 40,
},
form: {
marginTop: 39,
marginBottom: 115,
marginHorizontal: 30
},
textOff: {
color: 'gray',
fontSize: 28,
textTransform: 'none',
letterSpacing: 2,
left: 10
},
textOn: {
color: 'green',
fontSize: 28,
textTransform: 'none',
letterSpacing: 2,
left: 10
},
})
If you want to use booleans to keep track of selected option then I would go with one variable, because in case of radio buttons only one at a time can be selected so second boolean is redundant. Here is one example of doing it:
export default class ChooseOption extends Component {
constructor(props) {
super(props);
this.state = {
isOption1Selected: true,
preference: '',
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.greeting}>Select one option:</Text>
<View style={styles.form}>
<TouchableOpacity
onPress={() => this.setState({ isOption1Selected: true })}
style={{ flexDirection: 'row', alignItems: 'center' }}>
<View
name={this.state.isOption1Selected ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color={this.state.isOption1Selected ? 'green' : 'gray'}
/>
<Text
style={this.state.isOption1Selected ? styles.textOn : styles.textOff}>First Option</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => this.setState({ isOption1Selected: false })}
style={{ marginTop: 30, flexDirection: 'row', alignItems: 'center' }}>
<View
name={!this.state.isOption1Selected ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color={!this.state.isOption1Selected ? 'green' : 'gray'}
/>
<Text
style={!this.state.isOption1Selected ? styles.textOn : styles.textOff}>Second Option</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
But imagine if you have to add more options then it would be better to keep track of an id of selected option which you could implement in this way:
export default class ChooseOption extends Component {
constructor(props) {
super(props);
this.state = {
selectedOptionId: 0,
preference: '',
};
}
render() {
const { selectedOptionId } = this.state;
return (
<View style={styles.container}>
<Text style={styles.greeting}>Select one option:</Text>
<View style={styles.form}>
<TouchableOpacity
onPress={() => this.setState({ selectedOptionId: 0, preference: 'First option' })}
style={{ flexDirection: 'row', alignItems: 'center' }}>
<View
name={selectedOptionId === 0 ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color={selectedOptionId === 0 ? 'green' : 'gray'}
/>
<Text
style={selectedOptionId === 0 ? styles.textOn : styles.textOff}>First Option</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => this.setState({ selectedOptionId: 1, preference: 'Second option' })}
style={{ marginTop: 30, flexDirection: 'row', alignItems: 'center' }}>
<View
name={selectedOptionId === 1 ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color={selectedOptionId === 1 ? 'green' : 'gray'}
/>
<Text
style={selectedOptionId === 1 ? styles.textOn : styles.textOff}>Second Option</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => this.setState({ selectedOptionId: 2, preference: 'Third option' })}
style={{ marginTop: 30, flexDirection: 'row', alignItems: 'center' }}>
<View
name={selectedOptionId === 2 ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color={selectedOptionId === 2 ? 'green' : 'gray'}
/>
<Text
style={selectedOptionId === 2 ? styles.textOn : styles.textOff}>Third Option</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
And finally you could write a function to generate all the options from predefined array so that your code stays clean:
const options = [
{ id: 0, text: 'First option'},
{ id: 1, text: 'Second option'},
{ id: 2, text: 'Third option'},
]
export default class ChooseOption extends Component {
constructor(props) {
super(props);
this.state = {
selectedOptionId: 0,
preference: '',
};
}
createOption(optionData) {
const { selectedOptionId } = this.state;
const { id, text } = optionData;
return (
<TouchableOpacity
key={id}
onPress={() => this.setState({ selectedOptionId: id, preference: text })}
style={{ flexDirection: 'row', alignItems: 'center' }}>
<View
name={selectedOptionId === id ? 'md-radio-button-on' : 'md-radio-button-off'}
size={30}
color={selectedOptionId === id ? 'green' : 'gray'}
/>
<Text
style={selectedOptionId === id ? styles.textOn : styles.textOff}>{text}</Text>
</TouchableOpacity>
);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.greeting}>Select one option:</Text>
<View style={styles.form}>
{
options.map((op) => this.createOption(op))
}
</View>
</View>
);
}
}
UPDATE
If you want to print preference in console when it is selected, you can do something similar to what you did first time by calling custom function in TouchableOpacity but in a bit different way: onPress={() => this.select(id, text)}
. And then define this function like:
select(id, text) {
this.setState({ selectedOptionId: id, preference: text });
console.log(text);
}
Option for what? Lets assume its for theme: option1 (dark) and option2 (light)
Lets say its option for themes
const THEMES = {
DARK: "dark",
LIGHT: "light"
};
state = {
selectedTheme : undefined,
preference: ''
}
chooseFirst = () => {
this.setState({ selectedTheme:THEMES.DARK })
}
chooseSecond = () => {
this.setState({ selectedTheme:THEMES.LIGHT })
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.