React native typescript: Why and how to use it to build an application

Typescripts nowadays becoming more popular in the technology world. The evidence for this is over 19 million downloads weekly on. After checking this article, you’ll know what Typescript is and how exactly Typescript is doing. Or If you have never heard about React Native Typescript so you’re in the right place. You’ll find another saving time way to develop your app

What is React native TypeScript?

React native typescript

TypeScript is an open source language that is built on top of JavaScript by Microsoft. Actually, it’s the same as JavaScript, but with static type definitions.

Advantages of using TypeScript in React Native

  1. Self Documentation: with clearly defined types, It becomes easy for other developers to understand your code. 
  2. Refactoring becomes easy: Typescript will verify again your code before running, that is why it will help you reduce the mistake percentage. 
  3. Easy Debugging: Fixing the errors becomes a lot easier with typescript because you have all the types documented in the code itself. 
  4. Valid Output: Unlike using Javascript, If you have written a valid typescript, then you can confidently say that it will generate a Valid JavaScript output.
  5. Text editor or IDE will also help you: editors and IDE are intergrated in TypeScript. This allows your editor to use TypeScript definitions and autocomplete the code and inform you what to pass to elements.
  6. It becomes easy to develop: By verifying types for the changes and functions, you get a structure of your entire app. It helps you take care more about scopes and the background of the whole app. You can easily grow your app.
  7. Can be adapted easily: Typescript is not a totally new language. If you are already familiar with javascript then you can easily move on to typescript.

Disadvantages of using TypeScript in React Native

  1. More elements need to be managed : You have to keep in mind the types of what you assigned values while creating objects. 
  2. New syntax: TypeScript is not a whole new programming language but still it comes with some new syntax. You have to adapt to it and it takes some time to get used to it.
  3. Need more time to proceed: You can get many benefits by using Typescript but it also needs a lot of time if compared to plain JavaScript.
  4. Lack of Knowledge:  JavaScript seems more popular than Typescript. So not everybody has knowledge in Typescript, you have to spend the time to learn how it works.

With all these pros and cons, Typescript still provides big value to your project. You will save many hours of fixing the error by using TypeScript. Hence, you should consider using TypeScript in your React Native Project.

The way to building an application with React Native TypeScript

React native typescript

You must understand what TypeScript is, and now we will see how to apply TypeScript and how TypeScript can improve your developer experience without getting too complex. 

Requirements to build an application with React Native Typescript

As we mentioned, it is not too complex but it doesn’t mean it is very easy and there is no need for any knowledge. Below are some requirements: 

  • Basic knowledge of running CLI commands
  • Node.js and npm installed on your computer
  • XCode or Android Studio installed on your computer
  • Basic knowledge of JavaScript
  • Basic knowledge of React
  • Some experience with React Native (suggested, not required)

Progress 

First, you need to run the command below in your terminal:

npx react-native init ShoppingList --template react-native-template-typescript

Applying that command will help create a new React Native project using a TypeScript template with the required dependencies and configurations in a folder called ShoppingList.

To know how you can use TypeScript in an existing application, take a look at the docs

Building the base UI

To start the project, you need to open the folder in your code editor and run the command as below:

# MacOS

npm run ios

# Windows/Linux

npm run android

The App.tsx element is the root element in our app. This element will include other elements we use in the app, and we’ll get back to it in a bit. For now, let’s build our first element.

Build a folder structure like src/components in the root directory and create a Header.tsx element in the components folder. 

As you can notice that the files we’re building have a .tsx extension? That’s because we’re now creating with TypeScript and we need to use the proper file extensions. If not, we’ll get errors in the regular .js files.

Then you need to paste the code below into the file:

import React from 'react';

import {View, Text, StyleSheet} from 'react-native';

interface Props {

  title: string;

}

const Header: React.FC<Props> = ({title}) => {

  return (

    <View style={styles.header}>

      <Text style={styles.headerText}>{title}</Text>

    </View>

  );

};

const styles = StyleSheet.create({

  header: {

    paddingVertical: 20,

    borderBottomWidth: 1,

    borderBottomColor: '#cfcfcf',

    alignItems: 'center',

  },

  headerText: {

    fontSize: 20,

    fontWeight: '600',

  },

});

export default Header;

In case you’re already familiar with React Native, you can ignore most of the code above. However,  please pay attention to lines 3-6:

interface Props {

  title: string;

}

const Header: React.FC<Props> = ({title}) => { /* content here*/}

Because we’re using TypeScript, we are now able to determine what our element should take in, how it should take in, and the time to take.

In the first three lines, we announced an interface, which serves as the structure for the props object we’d normally access in our element. However, this time we’re determining the tools and their types by using TypeScript.

The benefit of this way is that we get better IntelliSense and some validation when we’ll use the element. 

Back in the App.tsx element, replace the content by this code:

import React from 'react';

import {SafeAreaView, StyleSheet, Text, View} from 'react-native';

import Header from './src/components/Header';

const App = () => {

  return (

    <SafeAreaView style={styles.container}>

      <Header />

    </SafeAreaView>

  );

};

const styles = StyleSheet.create({

  container: {

    flex: 1,

    backgroundColor: '#e8e7e3',

  },

});

export default App;

Once again, you can notice a red line under the <Header/> element. If you hover over it, you should see a message that the element expects title prop that was not supplied. Let’s do that now.

And if you replace that line with the code snippet below, you can see that the error is gone:

<Header title="Shopping List" />

On the other hand, if you try to assign a number (or any other data type that isn’t a string) you’ll get a different error. This progress is TypeScript trying to help you find out bugs before they happen.

Adding items to the list

Build a new element, AddItem.tsx, to your /src/components folder and paste the code below also

import React, {useState} from 'react';

import {

  View,

  Text,

  TextInput,

  TouchableOpacity,

  StyleSheet,

} from 'react-native';

export interface IItem {

  item: string;

  quantity: string;

}

const AddItem = () => {

  const [item, setItem] = useState('');

  const [quantity, setQuantity] = useState('');

  return (

    <View>

      <Text style={styles.heading}>Add Shopping Item</Text>

      <View style={styles.form}>

        <TextInput

          style={styles.input}

          placeholder="Enter item"

          value={item}

          onChangeText={text => setItem(text)}

        />

        <TextInput

          style={styles.input}

          placeholder="Enter quantity"

          keyboardType="numeric"

          value={quantity}

          onChangeText={q => {

            setQuantity(q);

          }}

        />

        <TouchableOpacity style={styles.addItemButton} onPress={() => {}}>

          <Text style={styles.buttonText}>Add Item</Text>

        </TouchableOpacity>

      </View>

    </View>

  );

};

const styles = StyleSheet.create({

  heading: {

    fontSize: 20,

    fontWeight: '700',

  },

  form: {

    marginTop: 30,

  },

  input: {

    padding: 15,

    borderColor: 'rgba(0, 0, 0, 0.2)',

    borderWidth: 1,

    borderRadius: 5,

    marginBottom: 20,

  },

  addItemButton: {

    backgroundColor: '#eb8634',

    paddingVertical: 20,

    borderRadius: 5,

    alignItems: 'center',

  },

  buttonText: {color: '#fff', fontWeight: '500'},

});

export default AddItem;

Please notice the named export IItem on line 9. That’s the structure of an item in our shopping list, and we export it because we’ll be needing it in other elements.

Back to App.tsx, update the element with the code below:

import React, {useState} from 'react';

import {SafeAreaView, StyleSheet, Text, View} from 'react-native';

import Header from './src/components/Header';

import AddItem, {IItem} from './src/components/AddItem'; /* import AddItem and interface*/

const App = () => {

  const [shoppingList, setShoppingList] = useState<IItem[]>([]); // set the type of what the hook expects to be an array of IItems.

  return (

    <SafeAreaView style={styles.container}>

      <Header title="Shopping List" />

      <View style={styles.contentWrapper}>

        <AddItem

          setShoppingList={setShoppingList}

          shoppingList={shoppingList}

        />

      </View>

    </SafeAreaView>

  );

};

const styles = StyleSheet.create({

  container: {

    flex: 1,

    backgroundColor: '#e8e7e3',

  },

  contentWrapper: {

    padding: 20,

  },

});

export default App;

Now in App.tsx we imported the new AddItem element and the IItem confluence so we can use (on line 6) the useState hook to create the shoppingList state.

When you hover on the setShoppingList, you’ll see the type of it. You need to remember this one because we will need it soon when we add items to the shopping list in AddItem.tsx.

Go back to the AddItem.tsx element and update it with this:

import React, {useState} from 'react';

import {

  View,

  Text,

  TextInput,

  TouchableOpacity,

  StyleSheet,

  Alert,

} from 'react-native';

export interface IItem {

  item: string;

  quantity: string;

}

interface Props {

  setShoppingList: React.Dispatch<React.SetStateAction<IItem[]>>;

  shoppingList: IItem[];

}

const AddItem: React.FC<Props> = ({shoppingList, setShoppingList}) => {

  const [item, setItem] = useState('');

  const [quantity, setQuantity] = useState('');

  const addItem = () => {

    if (!item) {

      Alert.alert('No Item!', 'You need to enter an item');

    } else {

      setShoppingList([

        ...shoppingList,

        {

          item,

          quantity: quantity || '1',

        },

      ]);

      setItem('');

      setQuantity('');

    }

  };

  return (

    <View>

      <Text style={styles.heading}>Add Shopping Item</Text>

      <View style={styles.form}>

        <TextInput

          style={styles.input}

          placeholder="Enter item"

          value={item}

          onChangeText={text => setItem(text)}

        />

        <TextInput

          style={styles.input}

          placeholder="Enter quantity"

          keyboardType="numeric"

          value={quantity}

          onChangeText={q => {

            setQuantity(q);

          }}

        />

        <TouchableOpacity style={styles.addItemButton} onPress={addItem}>

          <Text style={styles.buttonText}>Add Item</Text>

        </TouchableOpacity>

      </View>

    </View>

  );

};

const styles = StyleSheet.create({

  heading: {

    fontSize: 20,

    fontWeight: '700',

  },

  form: {

    marginTop: 30,

  },

  input: {

    padding: 15,

    borderColor: 'rgba(0, 0, 0, 0.2)',

    borderWidth: 1,

    borderRadius: 5,

    marginBottom: 20,

  },

  addItemButton: {

    backgroundColor: '#eb8634',

    paddingVertical: 20,

    borderRadius: 5,

    alignItems: 'center',

  },

  buttonText: {color: '#fff', fontWeight: '500'},

});

export default AddItem;

There are compelling changes in the element now, so I’ll walk you through them.

On line 14, we found the Props confluence and set the type of each property, and then set it as the type of Props in our feature element on line 18.

We also built a handling feature on line 21, when clicking to the “Add Item”, the function checks if an item was entered in the field, then invokes the setShoppingList() function to add a new item to the list. 

Listing out items

Proceed until this step, you might be able to add new items, let’s create an element to list them out.

Creating another file in /src/components named Item.tsx and paste the code below inside:

import React from 'react';

import {View, Text, StyleSheet} from 'react-native';

import {IItem} from './AddItem';

const Item: React.FC<IItem> = ({item, quantity}) => {

  return (

    <View style={styles.item}>

      <Text style={styles.itemName}>{item}</Text>

      <Text style={styles.quantity}>x{quantity}</Text>

    </View>

  );

};

const styles = StyleSheet.create({

  item: {

    padding: 20,

    flexDirection: 'row',

    justifyContent: 'space-between',

    alignItems: 'center',

    borderBottomWidth: 1,

    borderBottomColor: 'rgba(0, 0, 0, 0.2)',

  },

  itemName: {

    fontWeight: '500',

  },

  quantity: {

    padding: 6,

    borderWidth: 1,

    borderColor: 'rgba(0, 0, 0, 0.2)',

    borderRadius: 10,

    overflow: 'hidden',

    backgroundColor: 'rgba(0, 0, 0, 0.05)',

  },

});

export default Item;

You probably get it already! The Item.tsx element accepts properties from IItem as props, and then we show them with some styling.

Now we need to finish up the app by importing the element into App.tsx and listing the items using the built-in A[FlatList](https://reactnative.dev/docs/flatlist)element.

The last step is replace the content of the App.tsx with the code below:

import React, {useState} from 'react';

import {SafeAreaView, StyleSheet, View, FlatList} from 'react-native';

import Header from './src/components/Header';

import AddItem, {IItem} from './src/components/AddItem';

import Item from './src/components/Item';

const App = () => {

  const [shoppingList, setShoppingList] = useState<IItem[]>([]);

  return (

    <SafeAreaView style={styles.container}>

      <Header title="Shopping List" />

      <View style={styles.contentWrapper}>

        <AddItem

          setShoppingList={setShoppingList}

          shoppingList={shoppingList}

        />

        <FlatList

          data={shoppingList}

          keyExtractor={(item, index) => `${item.item}-${index}`}

          renderItem={({item}) => (

            <Item item={item.item} quantity={item.quantity} />

          )}

        />

      </View>

    </SafeAreaView>

  );

};

const styles = StyleSheet.create({

  container: {

    flex: 1,

    backgroundColor: '#e8e7e3',

  },

  contentWrapper: {

    padding: 20,

  },

});

export default App;

So our app is now complete. On line 16, we use the FlatList element to show items from our list, and you can see how we use the Item element in the renderItem prop for FlatList.

Conclusion

After this article we hope that can bring you the necessary knowledge, and you can find another way to develop your application. If you meet any trouble while developing, don’t hesitate to contact us, we’re always willing to support you. ONEXT DEGITAL with more than 10 years of development with expertise in web development, mobile app, UX/UI design,…We sure that can give you the best solution in shortest time ever. 

 

Read more

React native review: Everything you should know in 2023