The Talent500 Blog
React Native App With TypeScript Tutorial 1

React Native App With TypeScript Tutorial

Overview

Typescript is a superset of Javascript that employs static typing, classes, and interfaces and is hence referred to as an Object Oriented programming language (OOP). Many developers use it extensively to reduce mistakes and for type checking in apps. Adding a strict type makes the code more self-expressive. Because of the tight behaviour, developers may find it challenging to use typescript in their projects at times.
Any browser, device, or operating system can run Typescript code. Because typescript is a superset of Javascript, it compiles to Javascript, and every valid Javascript is also a valid Typescript. Typescript identifies problems at build time, reducing the likelihood of mistakes during runtime. The downside of Typescript over Javascript is that it takes longer to complete the code.
In this blog, we will learn about react native apps and typescript, as well as how to create a basic quiz application.

Create React Native App

To begin, run the following command to create a react native app.

react-native init QuizApp
cd QuizApp

Install Dependencies

Run the below command to install the dependencies,

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

Let’s look at what the installed typescript libraries are for.
typescript: This is to install typescript

  • @types/react: This is to install react types for typescript
  • @types/react-native: This is to install React Native types for typescript
  • @types/react-test-renderer: This is to install types for test-renderer for typescript
  • @types/jest: This is to install types for jest testing for typescript

We will need Axios for API calls as well as the library for the code parts. Run the following command to accomplish this,

npm install axios react-native-elements

TypeScript Configuration

Typescript must be configured in order for react-native to function. Using the tsc command, create a config file called tsconfig.json.

tsc –init

Note– You need to have typescript installed globally to use the tsc command.
Change App.js to App.tsx to construct your react native app with typescript.

Create Components

Let’s begin by making components for our application. Our basic Quiz application will include the following elements:
Screen
➡ Quiz.tsx Components
➡ Headers.tsx
➡ Questions.tsx
➡ Answers.tsx
➡ Buttons.tsx API Call
Now we’ll go over each component file one by one and examine the code.

// Headers.tsx

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:
interface Header {
title: string,
}
const HeaderClass: FC<Header>=(props) => {/*content*/}

In typescript, we may specify what to take and how to take it. In this case, we’ve established an interface called Header, which specifies a structure for the props object to use in order to access the component. To do so, specify propsTo, ‘title’ with the string type.
Here’s the advantage: it provides some validation when we utilise this component.
Furthermore, we have react native code that displays the content as a header title with a style set to it.

// Buttons.tsx

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;

We have an interface named Title in the file Buttons.tsx that carries the props structure. It adjusts the style based on the right response when pushing the button and disables additional buttons based on parent class properties.

// Answers.tsx

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;

We have an interface entitled Answers in this file that defines a response, useranswer, having another type interface AnswerObject (used in the class Quiz), correctanswer, and checkanswer method. This file displays the many alternatives for selecting a child class prop underneath the question.

// Question.tsx

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;

We have an interface called Question in this file that specifies props for QuestionNo and Question.

// Quiz.tsx

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 that appears upon loading. When the screen is shown, it changes all of the states to the starting phases and uses API to specify the questions and alternatives that will be displayed. When the API delivers data, the Question and Answers classes are invoked to render the items using props.
The answers class makes use of a method named checkanswer, which compares the current reference of the selected answer to the API’s right response. If they match, the score is increased by one and the question is moved on to the next.

// src/utils/api.tsx

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 code, we have an interface named Question, which includes a structure to utilise as props in our Quiz App to return the appropriate alternatives. It retrieves information from the API using the Axios library. It delivers the API result, which includes questions and responses depending on several parameters.
Github Repository: React Native App with Typescript
You can explore with code on Github or follow the methods outlined above to create a React Native app with Typescript.

Conclusion

So, this was all about using Typescript to create a simple React Native App. A little quiz app flow to help you learn how typescript works in react native. I hope your reason for visiting this lesson was successful. Visit the React Native tutorials page for additional similar lessons. We give step-by-step instructions covering both fundamental and advanced React Native knowledge, as well as source code for you to explore on your own.

0
Afreen Khalfe

Afreen Khalfe

A professional writer and graphic design expert. She loves writing about technology trends, web development, coding, and much more. A strong lady who loves to sit around nature and hear nature’s sound.

Add comment