James Stirrat
James Stirrat

Reputation: 101

React Native - Using State to Show/Hide Error Messages

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

Answers (2)

morteza moradi
morteza moradi

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

Sachin
Sachin

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

Related Questions