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.
- button text
- onPress
- type (filled or outlined)
- border (true or false)
- 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
By default its type is filled, large in size and without border.
Buttons.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
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
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
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.
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
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 (
{text}
)
}
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 you can find the github repo
Top comments (2)
A better approach to pass the button text is to use "props.children" and use it this way:
thank you