DEV Community

Cover image for Setup Vanilla React Native with TypeScript
Paul Oloyede
Paul Oloyede

Posted on • Edited on • Originally published at thecurios.hashnode.dev

Setup Vanilla React Native with TypeScript

An attempt to create a simple react native typescript project without the bells and whistles you get when using a template or boilerplate, seen to be a challenge and hardly is there any tutorial that covers these steps vividly.

So, while at it I enjoyed creating this blogpost and solving the problem highlighted above, hopefully you will enjoy it too!

A Little Backstory about React Native and TypeScript

React Native is an exciting framework that enables web developers to create robust mobile applications using their existing JavaScript knowledge. It offers faster mobile development, and more efficient code sharing across iOS, Android, and the Web, without sacrificing the end user’s experience or application quality.

It’s based on React, Facebook’s JavaScript library for building user interfaces, but instead of targeting the browser, it targets mobile platforms.
Web developers can now write mobile applications that look and feel truly “native,” all from the comfort of a JavaScript library that we already know and love. Plus, because most of the code you write can be shared between platforms, React Native makes it easy to simultaneously develop for both Android and iOS.

TypeScript is a superset of the JavaScript language that has a single open-source compiler and is developed mainly by a single vendor: Microsoft. The goal of TypeScript is to help catch mistakes early through a type system and to make JavaScript development more efficient.

Requirements

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

Getting Started

The first step is to install and initialise a project and it's dependencies. To achieve that we run this command in the terminal:

npx react-native init Foobaz 

Enter fullscreen mode Exit fullscreen mode

The above commands creates a project with the name Foobaz with the basic setup to run our JavaScript files.

Now that we have setup the project, here is what we get out of the box:

Screenshot 2022-04-01 at 12.52.18.png

The project created here gives us a barebone structure for pure JavaScript files or source code.
So we have to integrate TypeScript.

Integrate TypeScript

The next thing is to add typescript to our app. We add these packages @types/react @types/react-native react-native-typescript-transformer and integrate into our app:

yarn add typescript -D @types/react @types/react-native  react-native-typescript-transformer
Enter fullscreen mode Exit fullscreen mode

.ts is the default file extension while .tsx is a special extension used for files which contain JSX

Now that we've installed these packages, in our project root, we rename this file App.js to App.tsx, so we are able to write TypeScript code and let the compiler transform our source code.

The compiler is of no help to us until we tell it what to do. In TypeScript, these rules are defined in a special file called tsconfig.json.

Let's add a tsconfig.json file in the root of our project and paste in the following content:

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "isolatedModules": true,
    "jsx": "react-native",
    "lib": ["es2017"],
    "moduleResolution": "node",
    "noEmit": true,
    "strict": true,
    "target": "esnext"
  },
  "exclude": [
    "node_modules",
    "babel.config.js",
    "metro.config.js",
    "jest.config.js"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Compiling TypeScript Source Code

In our App.tsx file, you can replace the source code in there with the one below, where we are using the fetch api to pull users list and displaying in our app.

import React from 'react';
import {useState, useEffect} from 'react';
import {
  FlatList,
  ActivityIndicator,
  View,
  Text,
  StyleSheet,
  SafeAreaView,
  Pressable,
  Image,
} from 'react-native';


type DataItem = {
  id: string;
  first_name: string;
  last_name: string;
  email: string;
  avatar: string;
};


const App = () => {
  const [isLoading, setIsLoading] = useState(true);
  const [dataSource, setDataSource] = useState<DataItem[]>([]); //set the type of what the hook expects to be an array of DataItem.

  useEffect(() => {
    fetch('https://reqres.in/api/users?page=2')
      .then(response => response.json())
      .then((responseJson: {data: any}) => {
        setIsLoading(false);
        setDataSource(responseJson?.data);

      })
      .catch(error => {
        setIsLoading(false);
        // do something with the error...
      });
  }, []);

  if (isLoading) {
    return (
      <View
        style={{flex: 1, padding: 20, marginTop: 40, backgroundColor: 'white'}}>
        <ActivityIndicator />
      </View>
    );
  }
  return (
    <SafeAreaView
      style={styles.safeArea}>
      <FlatList
        data={dataSource}
        renderItem={({item}) => (
          <Pressable
          onPress={() => null}
          style={styles.cardContainer}>
          <View
            style={styles.cardContent}>
            <Image
              source={{uri: item?.avatar}}
              style={styles.avatar}
            />
            <View>
              <Text style={{color: '#000'}}>{item?.first_name} {item?.last_name}</Text>
            </View>
          </View>
        </Pressable>
        )}
        keyExtractor={({id}, index) => id}
      />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  safeArea: {
    backgroundColor: 'white',
    flex: 1,
    marginTop: 80,
    marginHorizontal: 16,
  },
  avatar: {
    height: 60,
    width: 55,
    marginLeft: 16,
    marginRight: 15,
    borderRadius: 35,
    justifyContent: 'center',
    alignItems: 'center',
  },
  cardContainer: {
    marginBottom: 10,
    flexDirection: 'row',
    paddingVertical: 16,
    backgroundColor: '#EEEFF2',
    alignItems: 'center',
    justifyContent: 'space-between',
    borderRadius: 8,
    shadowColor: '#EEEFF2',
    shadowRadius: 50,
    shadowOffset: {
      width: 0,
      height: 10,
    },
    shadowOpacity: 0.1,
    elevation: 5,
  },
  cardContent: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  }
});

export default App;

Enter fullscreen mode Exit fullscreen mode

In our App.tsx on line 15 we construct a data type to define the users list expected from our api endpoint.

On line 25 we declare a useState hook for conditional rendering to check if the data has loaded.

Also, on line 26 we declare a useState hook to hold our data to be rendered in our UI. We specified that the hook should accept an array of DataItem.

On line 53 we use the FlatList component, in-built into the react native package to display our UI.
FlatList is used to render list of data with minimal effort.

Running Our App

Let's navigate to the root folder in our project from a code editor and run the commands below to build the UI and start the application:

# MacOS
yarn run ios

Enter fullscreen mode Exit fullscreen mode
# Windows/Linux
yarn run android

Enter fullscreen mode Exit fullscreen mode

This is what our app should look like:
whitereactmobappvanilla.png

You can view the source code on GitHub here

Conclusion

Hurray!!! We are done at the moment.

Hope you enjoyed the tutorial and you were able to follow through without any errors?

Would appreciate your comments and suggestions about the tutorial in comment box.

Also, you can reach me on twitter @ayopaulofficial and on LinkedIn at Paul Oloyede

Thanks for Reading.

Top comments (0)