Quick Summary

In this tutorial guide, we will cover how to build React Native apps with Typescript. Using React Native and Typescript will improve code maintainability with static typing, support IDE, decrease runtime errors, and develop an efficient application.

Table of Contents

Overview

Typescript is a superset of Javascript that uses static typing, classes, and interfaces and is hence called an Object-Oriented programming language (OOP). Many developers widely use it to minimize errors and check application type. Adding a strict type makes it a more self-expressive code. Due to the strict behavior, sometimes developers find it challenging to work with Typescript in their projects.

Typescript code can be run on any browser, device, or operating system. Since it is a superset of Javascript, it compiles into JS, and every valid Javascript is a valid Typescript. It also detects bugs at the compile-time, so the chances of getting errors reduce at the runtime. Typescript has a disadvantage over Javascript in that it takes time to complete the code.

In this tutorial, we will learn about React native app with Typescript and see how can we build a basic quiz application.

Step-by-step guide on how to create React Native App

Initially, you need to create a React native app by using the below command.

Copy Text
react-native init QuizApp
cd QuizApp

Install Dependencies

Use the below command to install the dependencies.

Copy Text
npm install typescript @types/react @types/react-native 
@types/react-test-renderer @types/jest

Let’s see the purpose of the installed Typescript libraries.

  • typescript: To install Typescript
  • @types/react: To install react types for Typescript
  • @types/react-native: To install React Native types for Typescript
  • @types/react-test-renderer: To install types for test-renderer for Typescript
  • @types/jest: To install types for jest testing for Typescript

We will require Axios for API calls and the library required for the elements used in code. Run the below command for the same.

Copy Text
npm install axios react-native-elements

TypeScript Configuration

We need to configure Typescript for react-native to work. Create a config file named tsconfig.json using the tsc command.

Copy Text
tsc --init

Note– To use the tsc command, you need to have Typescript installed globally.

In order to build your react native app with Typescript, change App.js to App.tsx.

Create Components

Let’s get started with creating components for our application. Our basic Quiz application will consist of the following components-

  • Screen
  • ➡ Quiz.tsx

  • Components
  • ➡ Headers.tsx
    ➡ Questions.tsx
    ➡ Answers.tsx
    ➡ Buttons.tsx

  • API Call

Now, we will go through each component file step by step and look into the code.

// Headers.tsx

Copy Text
import React, {FC} from 'react';
import {SafeAreaView, StyleSheet, Text, StatusBar} from 'react-native';
 
interface Header {
 title: string;
}
const HeaderClass: FC<Header> = props => {
 return (
   <SafeAreaView>
     <StatusBar backgroundColor="white" />
     <Text style={styles.textstyle}>{props.title}</Text>
   </SafeAreaView>
 );
};
 
const styles = StyleSheet.create({
 textstyle: {
   textAlign: 'center',
   fontSize: 18,
 },
});
 
export default HeaderClass;

Explanation:

Copy Text
interface Header {
 title: string,
}
const HeaderClass: FC<Header>=(props) => {/*content*/}

In typescript, we can define what to take and how to take in the component. Here, we have declared an interface named Header, which defines a structure for the props object to access the component. For that, define propsTo, ‘title’ with a specific type ‘string.’

Here comes the benefit- it gives us some validation when we use this component.

Moreover, we have react native code which shows the text as header title with style defined to it.

// Buttons.tsx

Copy Text
import React, {FC} from 'react';
import {useEffect} from 'react';
import {SafeAreaView, StyleSheet, Text, TouchableOpacity} from 'react-native';
 
interface Title {
 key: number;
 answer: string;
 onPress: () => void;
 correct: boolean;
 disabled: boolean;
}
 
const Buttons: FC<Title> = props => {
 useEffect(() => {}, []);
 return (
   <SafeAreaView>
     <TouchableOpacity
       style={{
         backgroundColor: !props.disabled ? '#F5F5DC' : '#F5DEB3',
         width: '80%',
         elevation: 5,
         justifyContent: 'center',
         alignContent: 'center',
         marginLeft: 27,
         height: 38,
         marginTop: 10,
       }}
       onPress={() => {
         props.onPress();
       }}>
       <Text
         style={[
           styles.textstyle,
           {color: props.correct ? 'brown' : 'black'},
         ]}>
         {props.answer}
       </Text>
     </TouchableOpacity>
   </SafeAreaView>
 );
};
 
const styles = StyleSheet.create({
 textstyle: {
   textAlign: 'left',
   fontSize: 17,
   marginLeft: 8,
 },
});
 
export default Buttons;

In the file Buttons.tsx, we have an interface named Title which holds the structure for props. It changes style according to the correct answer on pressing the button and disables other buttons according to passed props from the parent class.

Need a developer to develop a React Native app with TypeScript?

Our TypeScript developers can help you minimize errors and seamlessly make your app more engaging and user-friendly.

// Answers.tsx

Copy Text
import React, {FC} from 'react';
import {SafeAreaView, StyleSheet, View} from 'react-native';
import Buttons from '../components/Buttons';
import {AnswerObject} from '../screens/Quiz';
 
interface Answers {
 useranswer: AnswerObject | undefined;
 answers: string[];
 setcorrectanswer: any;
 checkanswer: () => void;
}
 
const Answers: FC<Answers> = props => {
 return (
   <SafeAreaView>
     <View style={{marginTop: 10, paddingHorizontal: 20}}>
       {props.answers.map((answer, key) => {
         return (
           <View key={answer}>
             <Buttons
               {...{key, answer}}
               correct={props.useranswer?.correctanswer === answer}
               disabled={props.useranswer ? true : false}
               onPress={() => {
                 (props.setcorrectanswer.current = answer),
                   props.checkanswer();
               }}
             />
           </View>
         );
       })}
     </View>
   </SafeAreaView>
 );
};
 
const styles = StyleSheet.create({
 questioncontainer: {
   flexDirection: 'row',
   alignItems: 'center',
   backgroundColor: 'white',
   marginTop: 10,
   paddingRight: 16,
 },
 
 textstyle: {padding: 15, fontSize: 15, color: 'blue'},
});
 
export default Answers;

In this file, we have an interface named Answers which defines an answer, useranswer, having another type interface AnswerObject (used in the class Quiz), correctanswer, checkanswer function. This file shows the multiple options below the question to choose from the prop of the child class.

// Question.tsx

Copy Text
import React, {FC} from 'react';
import {SafeAreaView, StyleSheet, Text, View} from 'react-native';
 
interface Question {
 QuestionNo: number;
 Question: string;
}
 
const Questions: FC<Question> = props => {
 return (
   <SafeAreaView>
     <View style={styles.questioncontainer}>
       <Text style={styles.textstyle}>{props.QuestionNo}</Text>
       <Text
         style={{
           fontSize: 15,
           color: 'black',
           textAlign: 'left',
           marginRight: 7,
         }}>
         {props.Question}
       </Text>
     </View>
   </SafeAreaView>
 );
};
 
const styles = StyleSheet.create({
 questioncontainer: {
   flexDirection: 'row',
   alignItems: 'center',
   backgroundColor: 'white',
   marginTop: 10,
   paddingRight: 16,
 },
 
 textstyle: {padding: 15, fontSize: 15, color: 'blue'},
});
 
export default Questions;

In this file we have an interface named Question which defines props for QuestionNo and Question.

// Quiz.tsx

Copy Text
import React, {FC, useEffect, useRef, useState} from 'react';
import {
 StyleSheet,
 Text,
 View,
 TouchableOpacity,
 ActivityIndicator,
} from 'react-native';
import {getquestiojns, Question} from '../utils/api';
import Questions from '../components/Question';
import Answers from '../components/Answers';
import {Icon} from 'react-native-elements';
 
export type AnswerObject = {
 question: string;
 answer: string;
 correct: boolean;
 correctanswer: string;
};
 
const Quiz: FC = props => {
 const [loader, setloader] = useState(false);
 const [question, setquestion] = useState<Question[]>([]);
 const [useranswers, setuseranswers] = useState<AnswerObject[]>([]);
 const [score, setscore] = useState(0);
 const [number, setnumber] = useState(0);
 const [totalquestion] = useState(10);
 const [gameover, setgameover] = useState(true);
 const setcorrectanswer = useRef(null);
 const [correcta, setcorrecta] = useState('');
 
 useEffect(() => {
   startQuiz();
 }, []);
 const startQuiz = async () => {
   setnumber(0);
   setloader(true);
   setgameover(false);
   const newquestions = await getquestiojns();
   console.log(newquestions);
   setquestion(newquestions);
   setscore(0);
   setuseranswers([]);
   setloader(false);
 };
 const nextQuestion = () => {
   const nextq = number + 1;
   if (nextq == totalquestion) {
     setgameover(true);
   } else {
     setnumber(nextq);
   }
 };
 const checkanswer = () => {
   if (!gameover) {
     const answer = setcorrectanswer.current;
 
     const correcta = question[number].correct_answer === answer;
 
     if (correcta) setscore(prev => prev + 1);
 
     const answerobject = {
       question: question[number].question,
       answer,
       correcta,
       correctanswer: question[number].correct_answer,
     };
 
     setuseranswers(prev => [...prev, answerobject]);
     setTimeout(() => {
       nextQuestion();
     }, 1000);
   }
 };
 
 return (
   <View style={{flex: 1}}>
     {!loader ? (
       <View>
         <View style={styles.container}>
           <Text style={styles.textstyle}>Questions</Text>
           <Text style={styles.textstyle}>
             {number + 1}/{totalquestion}
           </Text>
         </View>
         <View style={{marginLeft: 20}}>
           <Text style={styles.textstyle}>Score : {score}</Text>
         </View>
         {question.length > 0 ? (
           <>
             <Questions
               QuestionNo={number + 1}
               Question={question[number].question}
             />
             <Answers
               answers={question[number].answers}
               {...{setcorrectanswer, checkanswer}}
               useranswer={useranswers ? useranswers[number] : undefined}
             />
           </>
         ) : null}
       </View>
     ) : (
       <ActivityIndicator
         style={{justifyContent: 'center', top: 200}}
         size={50}
         color="black"
       />
     )}
 
     <View>
       {!gameover && !loader && number != totalquestion - 1 ? (
         <TouchableOpacity onPress={() => nextQuestion()}>
           <Icon
             name="arrowright"
             size={40}
             color="black"
             type="antdesign"
             style={{left: 130, margin: 20}}
           />
         </TouchableOpacity>
       ) : number == totalquestion - 1 ? (
         <TouchableOpacity onPress={() => startQuiz()}>
           <Icon
             name="controller-play"
             size={40}
             color="black"
             type="entypo"
             style={{left: 130, margin: 20}}
           />
         </TouchableOpacity>
       ) : null}
     </View>
   </View>
 );
};
 
const styles = StyleSheet.create({
 container: {
   flexDirection: 'row',
   justifyContent: 'space-between',
   marginTop: 70,
   backgroundColor: 'white',
 },
 textstyle: {padding: 15, fontSize: 15, color: 'blue'},
 bottomview: {
   padding: 13,
   backgroundColor: 'blue',
   borderRadius: 300,
   width: 70,
   height: 70,
   position: 'absolute',
   right: 20,
   top: 550,
 },
 questioncontainer: {
   flexDirection: 'row',
   alignItems: 'center',
   backgroundColor: 'white',
   marginTop: 10,
   paddingRight: 16,
 },
 iconstyle: {
   backgroundColor: 'blue',
   borderRadius: 50,
   width: 70,
   height: 70,
   margin: 5,
   top: 100,
   left: 260,
 },
});
 
export default Quiz;

This is the main screen which is shown on loading. When the screen gets rendered, it sets all the states to the initial phases and calls API to set questions and options to display. When API returns data, the Question and Answers classes are called to render the items with the help of props.

The answers class uses a function called checkanswer, which checks the current reference of the selected answer and checks it with the API’s correct answer. If they match, then the score gets increased by one and proceeds to the next question.

Want to leverage the advanced features of the New React Native Architecture?
Hire React Native developer from us who will bring the best of React ecosystem to outshine your cross-platform mobile application at the top

// src/utils/api.tsx

Copy Text
import axios from 'axios';
 
export const _ = (array: any[]) => [...array].sort(() => Math.random() - 0.7);
 
export type Question = {
 category: string;
 incorrect_answers: string[];
 correct_answer: string;
 difficulty: string;
 question: string;
 type: string;
};
export const getquestiojns = async () => {
 const endpoint = 'https://opentdb.com/api.php?amount=10&category=9';
 const promise = await axios.get(endpoint);
 return promise.data.results.map((question: Question) => ({
   ...question,
   answers: _([...question.incorrect_answers, question.correct_answer]),
 }));
};

In this file, we have an interface named Question, which has a structure to use as props to return the desired options in this Quiz App. It uses the Axios library to fetch details from the API. It returns the result from API, which has questions and answers based on multiple options.

These were the tutorials for React Native with TypeScript. However, if you are still confused about whether to opt for it, you can contact a React Native app development company. They will simplify the process and guide you through it.

Github Repository: React Native App with Typescript

You can visit here – Github Repository and play around with code or follow the steps React Native app with Typescript.

Conclusion

So, this was all about building a basic React Native App with Typescript. A simple Quiz application flow will help you understand how Typescript works in React Native. To learnl more about React Native, you can check out our React Native tutorial page. We have step-by-step instructions and guidelines regarding React Native development and source code for you to explore on your own.

Want to Know Why and When to Use React Native App With TypeScript?

Connect Now

Build Your Agile Team

Hire Skilled Developer From Us

[email protected]

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.

How Can We Help You?