loading...
Cover image for Create a FormBuilder component in React Native (Part 2)

Create a FormBuilder component in React Native (Part 2)

dev_nope profile image Vasile Stefirta πŸ‡²πŸ‡© ✈️ πŸ‡ΊπŸ‡Έ ・4 min read

This series contents:

Part 2: Create a simple Salary Calculator Form

We'll start by creating a very basic form with two text inputs and two buttons. The updated App.js file should look something like this:

import React, { Component } from 'react';
import {
    StyleSheet,
    KeyboardAvoidingView,
    Text,
    Keyboard,
    TextInput,
    TouchableOpacity,
    Alert,
} from 'react-native';

export default class App extends Component {
    constructor(props) {
        super(props);

        // define the initial state, so we can use it later
        // when we'll need to reset the form
        this.initialState = { hourlyRate: '', hoursPerWeek: '' };

        this.state = this.initialState;
    }

    /**
     * Grab user's input data and do the math.
     */
    handleSubmit = () => {
        // using Javascript object destructuring to
        // get user's input data from the state.
        const { hourlyRate, hoursPerWeek } = this.state;

        // hide the keyboard
        // NOTE: the keyboard seems to show up after being dismissed
        //       when using the Alert react native component.
        //       Not a big deal at the moment (this is fine 😜).
        Keyboard.dismiss();

        // make sure we have some numeric values to work with
        if (!parseFloat(hourlyRate) || !parseFloat(hoursPerWeek)) {
            Alert.alert('Input error', 'Please input some positive numeric values.');
            return;
        }

        // do the Math
        const annualIncome = Math.abs(parseFloat(hourlyRate) * parseFloat(hoursPerWeek) * 52);

        // show results
        Alert.alert(
            'Your input and result',
            `$/hour: ${hourlyRate},\n Hours/week: ${hoursPerWeek}, \n Annual Income: $${annualIncome}`,
        );
    };

    /**
     * Reset the form and hide the keyboard.
     */
    resetForm = () => {
        Keyboard.dismiss();
        this.setState(this.initialState);
    };

    render() {
        const { hourlyRate, hoursPerWeek } = this.state;

        return (
            <KeyboardAvoidingView behavior="padding" style={styles.container}>
                <Text style={styles.screenTitle}>Salary Calculator</Text>
                <TextInput
                    style={styles.textInput}
                    placeholder="$/hour"
                    keyboardType="numeric"
                    returnKeyType="done"
                    blurOnSubmit
                    onChangeText={text => this.setState({ hourlyRate: text })}
                    value={hourlyRate}
                />
                <TextInput
                    style={styles.textInput}
                    placeholder="Hours/week"
                    keyboardType="numeric"
                    returnKeyType="done"
                    blurOnSubmit
                    onChangeText={text => this.setState({ hoursPerWeek: text })}
                    value={hoursPerWeek}
                />

                <TouchableOpacity style={styles.button} onPress={this.handleSubmit}>
                    <Text style={styles.buttonText}>Calculate</Text>
                </TouchableOpacity>

                <TouchableOpacity style={styles.button} onPress={this.resetForm}>
                    <Text style={styles.buttonText}>Reset</Text>
                </TouchableOpacity>
            </KeyboardAvoidingView>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        paddingHorizontal: 20,
        backgroundColor: '#3F4EA5',
    },
    screenTitle: {
        fontSize: 35,
        textAlign: 'center',
        margin: 10,
        color: '#FFF',
    },
    textInput: {
        height: 40,
        borderColor: '#FFF',
        borderWidth: 1,
        borderRadius: 3,
        backgroundColor: '#FFF',
        paddingHorizontal: 10,
        marginBottom: 10,
        fontSize: 18,
        color: '#3F4EA5',
    },
    button: {
        backgroundColor: '#FD6592',
        borderRadius: 3,
        height: 40,
        marginBottom: 10,
        justifyContent: 'center',
        alignItems: 'center',
    },
    buttonText: {
        color: '#FFF',
        fontWeight: 'bold',
        fontSize: 16,
    },
});

And as a result we'll end up having a calculator screen which looks and works like this:

Salary Calculator

So what do we have here?

  • a main container created using the KeyboardAvoidingView component. You can normally use simple View components to create containers, but when you're dealing with showing/hiding the virtual keyboard, then it's recommended to use KeyboardAvoidingView to improve user's experience.

  • a form title created via a Text component

  • two text inputs to ask the user what's its hourlyRate and how many hoursPerWeek are billable. We use the TextInput for that. This component has an onChangeText prop that takes a function to be called every time the text changed. We use that prop to store the user's input into the state. That way we can easily access and manipulate that value anywhere in our component.

  • a submit button created using the TouchableOpacity. We could also use the default Button component to create a button, but this one doesn't allow much customization when it comes to UI changes. Both the TouchableOpacity and Button components accept an onPress prop which takes a function to be called when the user taps the button.

  • a reset button which resets both text inputs and hides the virtual keyboard when tapped.

For a full list of changes, check out this commit on GitHub.


Now that we have this simple form ready, let's move on to Part 3 of this series where we'll create some wrapper components for our text inputs and buttons.

Discussion

pic
Editor guide