Create a FormBuilder component in React Native (Part 7)
Tags: react, reactnative, ios, javascript
Published: 2019-03-18 01:07:29

---
title: Create a FormBuilder component in React Native (Part 7)
published: true
description: 
tags: react, react-native, ios, javascript
cover_image: https://thepracticaldev.s3.amazonaws.com/i/68ghwpyr8mvgumn2edca.jpeg
series: Create a FormBuilder component in React Native
---

This series contents:
- [Part 1: Create a new React Native app](https://dev.to/dev_nope/create-a-formbuilder-component-in-react-native-intro--part-1-1m84)
- [Part 2: Create a simple Salary Calculator Form](https://dev.to/dev_nope/create-a-formbuilder-component-in-react-native-part-2-2dec)
- [Part 3: Create custom form input and button components](https://dev.to/dev_nope/create-a-formbuilder-component-in-react-native-part-3-1aib)
- [Part 4: Work on the `FormBuilder` component](https://dev.to/dev_nope/create-a-formbuilder-component-in-react-native-part-4-5gc3)
- [Part 5: Enable/disable form buttons on-the-fly](https://dev.to/dev_nope/create-a-formbuilder-component-in-react-native-part-5-535h)
- [Part 6: Create a Sign Up form](https://dev.to/dev_nope/create-a-formbuilder-component-in-react-native-part-6-2ohd)
- Part 7: Add support for Boolean field type (current)

# Part 7: Add support for Boolean field type

Now that we verified that our `FormBuilder` worked perfectly fine while creating a new form, let's see how we can add support for a new field type - a `Boolean` field in our case.

### Create a new `FormBooleanInput` component

Let's start by creating a new custom component which will render out a Boolean field for us. We'll call it `FormBooleanInput`:

```jsx
import React from 'react';
import PropTypes from 'prop-types';
import {
    View, Switch, Text, StyleSheet,
} from 'react-native';

/**
 * A stateless function component which renders a Boolean input (Switch).
 *
 * @param {obj} props
 */
const FormBooleanInput = (props) => {
    const { labelText, ...inputProps } = props;

    return (
        <View style={styles.switchWrapper}>
            <Switch {...inputProps} />
            {labelText && <Text style={styles.label}>{labelText}</Text>}
        </View>
    );
};

FormBooleanInput.propTypes = {
    labelText: PropTypes.string,
};

FormBooleanInput.defaultProps = {
    labelText: null,
};

const styles = StyleSheet.create({
    switchWrapper: {
        flex: 1,
        marginBottom: 15,
        paddingHorizontal: 10,
        flexDirection: 'row',
        alignItems: 'center',
    },
    label: {
        flex: 1,
        color: '#FFF',
        marginLeft: 10,
    },
});

export default FormBooleanInput;
```

As you can see it's a pretty basic component which renders out a [Switch](https://facebook.github.io/react-native/docs/switch) React Native component along with a label (if provided).

### Add a new field to the `Sign Up` form

Let's use the Sign Up form we created in our last post and add a new field to it, which hypothetically will allow users to subscribe to a mailing list. The field's "definition" would look like this:

```javascript
[
    {
        name: 'subscribe',
        label: 'Subscribe me to weekly news from Tech world.',
        type: 'boolean',
        defaultValue: true,
    },
]
```

You've probably noticed the new `defaultValue` field property. We'll use it to allow us having default values for any of our form fields. See the next section for details about how we'll be implementing this logic.

### Add support for the `boolean` field within the `FormBuilder` component

Here we'll need to work on a couple of changes:

- Allow form fields to have predefined default values by using the `defaultValue` field's property. Let's create a helper function which will detect for us what should be the default value for a given field.

```javascript
/**
 * Determine what should be the default value
 * for a given field.
 */
getFormFieldDefaultValue = ({ defaultValue, type }) => {
    if (defaultValue !== undefined) {
        return defaultValue;
    }

    switch (type) {
    case 'boolean':
        return false;
    default:
        return '';
    }
};
```

Now we can make use of this function within our `constructor()` like so:

```javascript
const formFieldNames = formFields.reduce((obj, field) => {
    obj[field.name] = this.getFormFieldDefaultValue(field);
    return obj;
}, {});
```

- Update our `hasValidFormData()` helper function to ignore `boolean` field types simply because this type of fields will always have a value (either `true` or `false`). The updated version looks like this:

```javascript
hasValidFormData = () => {
    const formFields = this.getFormFields();
    const isFilled = formFields
        // filter out Boolean fields because they will always have a value
        .filter(field => field.type !== 'boolean')
        // check if all remaining fields have been filled out
        .every(field => !!this.state[field.name]);

    return isFilled;
};
```

- Update our `hasDirtyFormData()` helper function and use a different approach for detecting if a `boolean` field changed its value or not, like so:

```javascript
hasDirtyFormData = () => {
    const formFields = this.getFormFields();
    const isDirty = formFields.some((field) => {
        switch (field.type) {
        case 'boolean':
            // because Boolean fields will have a default value,
            // we need to check if the current value is not the default one
            return this.state[field.name] !== this.getFormFieldDefaultValue(field);

        default:
            return !!this.state[field.name];
        }
    });

    return isDirty;
};
```

- Create a new `renderBooleanInput()` helper function which will render out the `FormBooleanInput` component for us. The function it's not very different from the existing `renderTextInput()`. Probably the main difference is using [onValueChange](https://facebook.github.io/react-native/docs/switch#onvaluechange) prop instead of [onChangeText](https://facebook.github.io/react-native/docs/textinput#onchangetext).

```jsx
renderBooleanInput = ({ name, label, inputProps }) => (
    <FormBooleanInput
        {...inputProps}
        value={this.state[name]}
        onValueChange={(value) => {
            this.setState({ [name]: value });
        }}
        labelText={label}
        key={name}
    />
);
```

- And lastly, let's update our component's `render()` function and render out `boolean` fields (if any were provided).

```jsx
{formFieldsRows.map((formFieldsRow, i) => (
    <View style={styles.row} key={`r-${i}`}>
        {formFieldsRow.map((field) => {
            switch (field.type) {
            case 'boolean':
                return this.renderBooleanInput(field);

            default:
                return this.renderTextInput(field);
            }
        })}
    </View>
))}
```

That's it! Let's take a look at how the form works at this point:

![Sign Up Form V2](https://thepracticaldev.s3.amazonaws.com/i/bqpahidel51rz5325c0p.gif "Sign Up Form V2")

For a full list of changes, check out this [commit on GitHub](https://github.com/vasilestefirta/react-native-form-builder/commit/87d8ca9417c15ead4825fcfe462f051cb3572061).

---

That's it my friends! 🙂🚀🚢 I think we've covered enough content to give you an idea on how to build your own `FormBuilder` component from scratch. 🏗️ Even though I'm going finish this series here, there are still so many things we can apply to this helper component (e.g. support for optional fields, support for new field types, etc.), but let's consider that as homework for you 👨‍💻👩‍💻.

---

### Bonus links 🎁

Here are some good resources I used to get started with React Native:
- https://reactjs.org/docs/getting-started.html (you'll have to understand how React works before diving into React Native)
- https://redux.js.org/basics (optional if you're just getting started with React Native, but when you'll be building more complex apps, you may need to reach out for Redux)
- https://facebook.github.io/react-native/
- http://www.reactnativeexpress.com/

Packages:
- https://reactnavigation.org (use this package when you want to navigate between screens or create some sort of tabbed application. It's very well documented and I had no issues using it.)
- https://github.com/react-native-community (an awesome organization which created a lot of great packages for the community)
- https://github.com/zo0r/react-native-push-notification
- https://github.com/invertase/react-native-firebase

App Icons + Splash Screens setup (that's always a tricky part so the links below definitely helped me):
- https://medium.com/@scottianstewart/react-native-add-app-icons-and-launch-screens-onto-ios-and-android-apps-3bfbc20b7d4c
- https://medium.com/handlebar-labs/how-to-add-a-splash-screen-to-a-react-native-app-ios-and-android-30a3cec835ae

Happy coding! 👨‍💻👩‍💻👍