How To Create Custom Fully Responsive Text Component In React Native
Tags: reactnative, react, javascript, tutorial
Published: 2020-07-23 07:40:58

In this article, I am going to show you how you can create your custom Text Component for your React Native Project.

### **Create New Project**

_If you are new to mobile development_, the easiest way to get started is with Expo CLI. 

_If you are already familiar with mobile development_, you may want to use React Native CLI. 



*Expo CLI* 
```react
expo init MyApp
cd MyApp
``` 

*React Native CLI*

```react
npx react-native init MyApp
cd MyApp
```

For sake of simplicity I will be using Expo for creating new React Native project. Once we created new project, we create folder `src` where we put folder `components`. Inside folder `components` we create another folder for our custom text component MyText. Inside this folder add `index.js` file. So far project looks like this:

![React Native Custom Text Component](https://dev-to-uploads.s3.amazonaws.com/i/7uzk3w2t4n9r9bhoqz0r.png)

Our component `index.js` looks like this:

```javascript
import * as React from 'react';
import { Text } from 'react-native';

const MyText = ()=> {
    return (
        <Text>Custom Component</Text>
    );
};

export { MyText }
```

Now it is time to add custom props to our component. I will be adding most common props for general understanding concept. 

`h1` - for text size 48px
`h2` - for text size 32px
`h3` - for text size 20px
`h4` - for text size 18px
`h5` - for text size 16px
`p`- for smaller texts,
`bold`- for making text bold 
`italic` - for making text italic 
`title` - for passing text value
`style` - for custom styling 
`...rest` - other props  

```diff
import * as React from 'react';
import { Text } from 'react-native';


+ const MyText = ({ h1, h2, h3, h4, h5,  p, bold, 
+                   italic, title,style, ...rest })=> {
    return (
        <Text>{title}</Text>
    );
};

export { MyText }
```

Now lets pass our props to actual body of our component with appropriate styles.

```diff
import * as React from 'react';
import { Text } from 'react-native';

const MyText = ({ h1, h2, h3, h4, h5,  p, bold, 
                 italic, title,style, ...rest })=> {
    return (
+        <Text style={[
+           h1 && { fontSize: 48 },
+           h2 && { fontSize: 32 },
+           h3 && { fontSize: 20 },
+           h4 && { fontSize: 18 },
+           h5 && { fontSize: 16 },
+           p && { fontSize: 12 },
+           bold && { fontWeight: 'bold' },
+           italic && { fontStyle: 'italic'},
+           style
+       ]}{...rest}>{title}</Text>
    );
};

export { MyText }
```

Let's see what we have done so far. We will be testing our component inside `App.js`. First we import our component from `components` folder and call it inside `App.js`.

```javascript
import React from 'react';
import { StyleSheet, View } from 'react-native';

import { MyText } from './src/components/MyText'

export default function App() {
  return (
    <View style={styles.container}>
      <MyText title={'Header 1'} h1/>
      <MyText title={'Header 2'} h2/>
      <MyText title={'Header 3'} h3/>
      <MyText title={'Header 4'} h4/>
      <MyText title={'Header 5'} h5/>
      <MyText title={'Small Text'} p/>
      <MyText title={'Header 1'} h1 italic/>
      <MyText title={'Header 1'} h1 bold/>
      <MyText title={'Header 2'} h2 italic/>
      <MyText title={'Header 2'} h2 bold/>
      <MyText title={'Header 3'} h3 italic/>
      <MyText title={'Header 3'} h3 bold/>
      <MyText title={'Header 4'} h4 italic/>
      <MyText title={'Header 4'} h4 bold/>
      <MyText title={'Header 5'} h5 italic/>
      <MyText title={'Header 5'} h5 bold/>
      <MyText title={'Small Text'} p italic/>
      <MyText title={'Small Text'} p bold/>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

```
## **Result**
![React Native Jasur Kurbanov](https://dev-to-uploads.s3.amazonaws.com/i/7van35ia9die3u6uf9d4.png)

## Responsiveness 
We successfully created our custom Text component. Now lets handle responsiveness of our Text component. 
In order to do this, create `adjust.js` file inside `src` folder.

```javascript
import { PixelRatio, Dimensions} from 'react-native';

const pixelRatio = PixelRatio.get();
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;


const adjust = (size) => {
    if (pixelRatio >= 2 && pixelRatio < 3) {
        // iphone 5s and older Androids
        if (deviceWidth < 360) {
            return size * 0.95;
        }
        // iphone 5
        if (deviceHeight < 667) {
            return size;
            // iphone 6-6s
        } if (deviceHeight >= 667 && deviceHeight <= 735) {
            return size * 1.15;
        }
        // older phablets
        return size * 1.25;
    } if (pixelRatio >= 3 && pixelRatio < 3.5) {
        // catch Android font scaling on small machines
        // where pixel ratio / font scale ratio => 3:3
        if (deviceWidth <= 360) {
            return size;
        }
        // Catch other weird android width sizings
        if (deviceHeight < 667) {
            return size * 1.15;
            // catch in-between size Androids and scale font up
            // a tad but not too much
        }
        if (deviceHeight >= 667 && deviceHeight <= 735) {
            return size * 1.2;
        }
        // catch larger devices
        // ie iphone 6s plus / 7 plus / mi note 等等
        return size * 1.27;
    } if (pixelRatio >= 3.5) {
        // catch Android font scaling on small machines
        // where pixel ratio / font scale ratio => 3:3
        if (deviceWidth <= 360) {
            return size;
            // Catch other smaller android height sizings
        }
        if (deviceHeight < 667) {
            return size * 1.2;
            // catch in-between size Androids and scale font up
            // a tad but not too much
        }
        if (deviceHeight >= 667 && deviceHeight <= 735) {
            return size * 1.25;
        }
        // catch larger phablet devices
        return size * 1.4;
    } return size;
};

export default adjust
```

If to explain this file succinctly, this contains function that handles text size for multiply devices and platforms. 
Before passing our function to our component, it is worth to mention that currently we defined kind of 'static' value to our font size. Once we pass `adjust` function to our component based on device or platform it will automatically adjust Text size to the screen.

Passing `adjust` function to our component
```javascript
import * as React from 'react';
import { Text } from 'react-native';

import adjust from "../../adjust";

const MyText = ({ h1, h2, h3, h4, h5,  p, bold, 
                 italic, title,style, ...rest })=> {
    return (
        <Text style={[
            h1 && { fontSize: adjust(48) },
            h2 && { fontSize: adjust(32) },
            h3 && { fontSize: adjust(20) },
            h4 && { fontSize: adjust(18) },
            h5 && { fontSize: adjust(16) },
            p && { fontSize: adjust(12) },
            bold && { fontWeight: 'bold' },
            italic && { fontStyle: 'italic'},
            style
        ]}{...rest}>{title}</Text>
    );
};

export { MyText }

```
## **Final Result**.
You can see in this final result, how adjust function influences to our custom text component. 

Initially we passed font-size just as it is, without taking into account device or platform. However, when we pass `adjust` function our text component scales up.

![Jasur Kurbanov](https://dev-to-uploads.s3.amazonaws.com/i/4mnuuel383nxj8sbenma.gif)

Full source code of this project: [Github Link](https://github.com/jasurkurbanovinit/MyApp)

Feel free to comment my mistakes on comment below.

### **References:**

Adjust.js file were modified, original file given from [Galio Framework](https://github.com/galio-org/galio)

[React Native Docs](https://reactnative.dev/docs/environment-setup)