Reputation: 101
Have been building a small Todo App on React Native based on a tutorial, I want to add an error message to the app if the user tries to save a list without any characters.
I have created the message, the state and a conditional for the state that is linked into a View containing the message. Although now, the user cannot save a list at all and the error message is constantly visible.
export default class AddTodoModal extends React.Component {
backgroundColors = ['#171219', '#225560', 'grey', '#EDF060', '#F0803C', '#310D20']
state = {
name: '',
color: this.backgroundColors[0],
errorState: false
};
createTodo = () => {
const {name, color} = this.state
if ({name}.length > 0) {
tempData.push({
name,
color,
todos: []
})
}
return
this.setState({name: ""})
this.props.closeModal();
}
renderColors() {
return this.backgroundColors.map(color => {
return (
<TouchableOpacity
key={color}
style={[styles.colorSelect, {backgroundColor: color}]}
onPress={() => this.setState({color})}
/>
);
});
}
render() {
return(
<KeyboardAvoidingView style={styles.container} behavior="padding">
<TouchableOpacity style={{position: 'absolute', top: 64, right: 32}} onPress={() => this.props.closeModal()}>
<AntDesign name="close" size={24} color={colours.blue} />
</TouchableOpacity>
<View visible={this.state.errorState}>
<Text style={styles.errorMessage}>Please Enter a Value!</Text>
</View>
<View style={{alignSelf: 'stretch', marginHorizontal: 32}}>
<Text style={styles.title}>Create Todo List</Text>
<TextInput style={styles.input} placeholder="List Name?" onChangeText={text => this.setState({ name: text })}/>
<View style={{flexDirection: 'row', justifyContent: 'space-between', marginTop: 12 }}>{this.renderColors()}</View>
<TouchableOpacity style={[styles.createList, { backgroundColor: this.state.color}]}
onPress={this.createTodo}>
<Text style={styles.buttonText}>Create List</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
}
Update:
With the answer below, now error message appears but saving a list is blocked, even with a valid input.
export default class AddTodoModal extends React.Component {
backgroundColors = ['#171219', '#225560', 'grey', '#EDF060', '#F0803C', '#310D20']
state = {
name: '',
color: this.backgroundColors[0],
errorState: false
};
createTodo = () => {
const {name, color} = this.state
if ({name}.length > 0) {
tempData.push({
name,
color,
todos: []
})
this.setState({name: ""})
this.setState({errorState: false})
this.props.closeModal();
} else {
({name}.length = 0)
this.setState({errorState: true})
return
}
}
renderColors() {
return this.backgroundColors.map(color => {
return (
<TouchableOpacity
key={color}
style={[styles.colorSelect, {backgroundColor: color}]}
onPress={() => this.setState({color})}
/>
);
});
}
render() {
return(
<KeyboardAvoidingView style={styles.container} behavior="padding">
<TouchableOpacity style={{position: 'absolute', top: 64, right: 32}} onPress={() => this.props.closeModal()}>
<AntDesign name="close" size={24} color={colours.blue} />
</TouchableOpacity>
{this.state.errorState && <View>
<Text style={styles.errorMessage}>Please Enter a Value!</Text>
</View>}
<View style={{alignSelf: 'stretch', marginHorizontal: 32}}>
<Text style={styles.title}>Create Todo List</Text>
<TextInput style={styles.input} placeholder="List Name?" onChangeText={text => this.setState({ name: text })}/>
<View style={{flexDirection: 'row', justifyContent: 'space-between', marginTop: 12 }}>{this.renderColors()}</View>
<TouchableOpacity style={[styles.createList, { backgroundColor: this.state.color}]}
onPress={this.createTodo}>
<Text style={styles.buttonText}>Create List</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
}
Update:
Fixing if statement for correct display of error message
createTodo = () => {
const {name, color} = this.state
let nameLength = this.state.name.length;
if (nameLength > 0) {
this.setState({errorState: false})
tempData.push({
name,
color,
todos: []
})
this.setState({name: ""})
this.props.closeModal();
} else {
(nameLength === 0)
this.setState({errorState: true})
}
}
Upvotes: 0
Views: 3345
Reputation: 143
you can implement like this
render() {
return(
<KeyboardAvoidingView style={styles.container} behavior="padding">
<TouchableOpacity style={{position: 'absolute', top: 64, right: 32}} onPress={() => this.props.closeModal()}>
<AntDesign name="close" size={24} color={colours.blue} />
</TouchableOpacity>
{this.state.errorState ? <View> <Text style={styles.errorMessage}>Please Enter a Value!</Text> </View> :null}
<View style={{alignSelf: 'stretch', marginHorizontal: 32}}>
<Text style={styles.title}>Create Todo List</Text>
<TextInput style={styles.input} placeholder="List Name?" onChangeText={text => this.setState({ name: text })}/>
<View style={{flexDirection: 'row', justifyContent: 'space-between', marginTop: 12 }}>{this.renderColors()}</View>
<TouchableOpacity style={[styles.createList, { backgroundColor: this.state.color}]}
onPress={this.createTodo}>
<Text style={styles.buttonText}>Create List</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
Upvotes: 0
Reputation: 991
You can use condtional rendering instead of visible property.
export default class AddTodoModal extends React.Component {
backgroundColors = ['#171219', '#225560', 'grey', '#EDF060', '#F0803C', '#310D20']
state = {
name: '',
color: this.backgroundColors[0],
errorState: false
};
createTodo = () => {
const {name, color} = this.state
if ({name}.length > 0) {
tempData.push({
name,
color,
todos: []
})
}
return
this.setState({name: ""})
this.props.closeModal();
}
renderColors() {
return this.backgroundColors.map(color => {
return (
<TouchableOpacity
key={color}
style={[styles.colorSelect, {backgroundColor: color}]}
onPress={() => this.setState({color})}
/>
);
});
}
render() {
return(
<KeyboardAvoidingView style={styles.container} behavior="padding">
<TouchableOpacity style={{position: 'absolute', top: 64, right: 32}} onPress={() => this.props.closeModal()}>
<AntDesign name="close" size={24} color={colours.blue} />
</TouchableOpacity>
{this.state.errorState && <View>
<Text style={styles.errorMessage}>Please Enter a Value!</Text>
</View>}
<View style={{alignSelf: 'stretch', marginHorizontal: 32}}>
<Text style={styles.title}>Create Todo List</Text>
<TextInput style={styles.input} placeholder="List Name?" onChangeText={text => this.setState({ name: text })}/>
<View style={{flexDirection: 'row', justifyContent: 'space-between', marginTop: 12 }}>{this.renderColors()}</View>
<TouchableOpacity style={[styles.createList, { backgroundColor: this.state.color}]}
onPress={this.createTodo}>
<Text style={styles.buttonText}>Create List</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
);
}
}
Upvotes: 1