Make your own customized and reusable React Native button component
Tags: react, reactnative, beginners, javascript
Published: 2020-03-23 18:53:59

---
title: Make your own customized and reusable React Native button component
published: true
description: Customized and Reusable React Native Button Component
tags: react, reactnative, beginners, javascript
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/eu1tb32xiouemsnqsz86.jpg
---
Recently, I am working on a mobile app where I need couple of buttons on different screens, like one for submit, login, etc. 

I want to make a reusable button once for all that change its style, shape, and size by accepting props. 

When I researched I found couple of things. 
There are two kinds of buttons, that are mostly preferred, *outlined* and *filled*. Then we can add further properties to it as per our design like *size* and *shape*.

### How it will help
It will make our code look clean, precise and easily scalable.

### Lets Start
>I am assuming you know how to create a react native app and other basic things.

**Breakdown the task into pieces**

We know we need to pass 5 props.
1. button text
2. onPress
3. type (filled or outlined)
4. border (true or false)
5. size (large or small) 

Our button `text` (like Submit, Delete, etc) will always be different, so we will get the text via props, and each button will have different functionality for that we are passing `onPress` props too.

Our button will look like this

![](https://dev-to-uploads.s3.amazonaws.com/i/3cu9ikh4v2zbq35t7mbb.jpg)

By default its type is filled, large in size and without border.

**Buttons.js**
```js
import React from 'react'
import { Text, View, TouchableOpacity, Dimensions, StyleSheet } from 'react-native'


const width = Dimensions.get('window').width


const Button = ({ text, onPress }) => {
  return (
    <TouchableOpacity onPress={onPress}>
      <View style={styles.btnContainerStyle}>
        <Text style={styles.btnTextStyle}> {text} </Text>
      </View>
    </TouchableOpacity>
  )
}

const styles = StyleSheet.create({
  btnContainerStyle: {
    backgroundColor: '#3F51B5',
    paddingVertical: 8,
    width: width / 1.3,
    borderRadius: 5
  },
  btnTextStyle: {
    color: '#ffffff',
    fontSize: 16,
    textTransform: 'uppercase',
    textAlign: 'center',
    fontFamily: 'Quicksand-Medium'
  }
})

export default Button
```

**App.js**
```js
import React from 'react';
import { View } from 'react-native';
import Button from './src/components/Button';

const App = () => {

  const onPress = () => {
    alert('clicked')
  }

  return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Button
          text='Submit'
          onPress={onPress}
        />
      </View>
  );
};

export default App
```
**Size**
Lets play with size first. Right now our button just accepting two props `onPress` and `text`. We want its `size` to become *small* if we pass `size='small'` props to it.

It's pretty easy, for *large size*, we are dividing the total width of the device by 1.3, similarly, for *small size*, we will divide the width by 1.2

```js
const large = width / 1.3
const small = width / 2
const btnSize = size === 'large' ? large : small
```
In `StyleSheet`, `width` will be equal to `btnSize`.

First, it will check if the size props (that we are passing from `App.js`) is `small` or `large` then it will act accordingly. 

**Type**
Lets come to the type of button. Either we want *filled* or *outlined*.

We have noticed, if we change three properties, our button type will become *outlined* from *filled*. Those properties are `Background color`, `text color` and `border`.

By default, our button type is filled. So will say
 
```js
const btnBgColor = type === 'filled' ? '#3f51b5' : 'transparent'
const btnTextColor = type === 'filled' ? '#ffffff' : '#6371c2' 
const border = type === 'outlined' && { borderColor: '#e7e7e7', borderWidth: 2 }
```

Now background color will be `btnBgColor` and text color will be `btnTextColor`, and if type prop is `outlined` we are adding two more properties in button style.

**Border**
We are only left with `border radius`, it would be tackled similar way.

```js
const btnBorderRadius = bordered ? 30 : 5
```

**Optional**
Sometimes we want to make button disable too until the form is filled, for that, we can pass the `disabled` props and `Icon` can also be added.
We can make it more interactive by giving an effect on `onPress`.

In a similar way, we can make `TextInput` component reusable too. 

If this article helps you, let me know in the comment section. I will write more on react native.

This is how it looks like at the end

![](https://dev-to-uploads.s3.amazonaws.com/i/rc2x4ubisr0914nn2yhf.jpg)

### Complete code ###

* Button.js
```js
import React from 'react'
import { Text, View, TouchableOpacity, Dimensions } from 'react-native'


const width = Dimensions.get('window').width


const Button = ({ text, onPress, type = 'filled', bordered = false, size = 'large' }) => {
  const large = width / 1.3
  const small = width / 2
  const btnSize = size === 'large' ? large : small
  const btnBgColor = type === 'filled' ? '#3f51b5' : 'transparent'
  const btnTextColor = type === 'filled' ? '#ffffff' : '#6371c2'
  const btnBorderRadius = bordered ? 30 : 5

  const containerCommonStyle = {
    backgroundColor: btnBgColor,
    paddingVertical: 8,
    width: btnSize,
    borderRadius: btnBorderRadius
  }

  const textCommonStyle = {
    color: btnTextColor,
    fontSize: 16,
    textTransform: 'uppercase',
    textAlign: 'center',
    fontFamily: 'Quicksand-Medium'
  }

  const border = type === 'outlined' && { borderColor: '#e7e7e7', borderWidth: 2 }

  return (
    <TouchableOpacity onPress={onPress} activeOpacity={0.7}>
      <View style={[containerCommonStyle, border]}>
        <Text style={[textCommonStyle]}> {text} </Text>
      </View>
    </TouchableOpacity>
  )
}

export default Button
```

* App.js
```js
import React from 'react';
import { View } from 'react-native';
import Button from './src/components/Button';
import Spacer from './src/components/Spacer';
import Center from './src/components/Center';


const App = () => {

  const onPress = () => {
    alert('clicked')
  }

  return (
    <Center>
      <Button
        text='Submit'
        type='outlined'
        bordered
        size='small'
        onPress={onPress}
      />
      <Spacer />
      <Button
        text='Submit'
        type='outlined'
        bordered
        onPress={onPress}
      />
      <Spacer />
      <Button
        text='Submit'
        type='outlined'
        onPress={onPress}
      />
      <Spacer />
      <Button
        text='Submit'
        size='small'
        onPress={onPress}
      />
      <Spacer />
      <Button
        text='Submit'
        bordered
        onPress={onPress}
      />
      <Spacer />
      <Button
        text='Submit'
        onPress={onPress}
      />
    </Center>
  );
};

export default App
```
I have added `Center` component to center horizontally and vertically the items and `Spacer` for having some vertical space between two items.

[Here](https://github.com/AbdulBasit313/React-Native-Custom-Button) you can find the github repo