{"id":21585,"date":"2021-11-12T11:15:24","date_gmt":"2021-11-12T11:15:24","guid":{"rendered":"https:\/\/www.bacancytechnology.com\/blog\/?p=21585"},"modified":"2024-07-09T12:41:09","modified_gmt":"2024-07-09T12:41:09","slug":"react-native-app-with-typescript","status":"publish","type":"post","link":"https:\/\/www.bacancytechnology.com\/blog\/react-native-app-with-typescript","title":{"rendered":"React Native App With TypeScript Tutorial"},"content":{"rendered":"<h2>Quick Summary<\/h2>\n<p>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.  <\/p>\n<h2>Overview<\/h2>\n<p>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.<\/p>\n<p>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.<\/p>\n<p>In this tutorial, we will learn about <strong>React native app with Typescript<\/strong> and see how can we build a basic quiz application.<\/p>\n<h2>Step-by-step guide on how to create React Native App<\/h2>\n<p>Initially, you need to create a React native app by using the below command.<\/p>\n<pre>react-native init QuizApp\r\ncd QuizApp<\/pre>\n<h2>Install Dependencies<\/h2>\n<p>Use the below command to install the dependencies.<\/p>\n<pre>npm install typescript @types\/react @types\/react-native \r\n@types\/react-test-renderer @types\/jest<\/pre>\n<p>Let\u2019s see the purpose of the installed Typescript libraries. <\/p>\n<ul class=\"bullets text-left\">\n<li><strong>typescript:<\/strong> To install Typescript<\/li>\n<li><strong>@types\/react:<\/strong> To install react types for Typescript<\/li>\n<li><strong>@types\/react-native:<\/strong> To install React Native types for Typescript<\/li>\n<li><strong>@types\/react-test-renderer:<\/strong> To install types for test-renderer for Typescript<\/li>\n<li><strong>@types\/jest:<\/strong> To install types for jest testing for Typescript<\/li>\n<\/ul>\n<p>We will require Axios for API calls and the library required for the elements used in code. Run the below command for the same.<\/p>\n<pre>npm install axios react-native-elements<\/pre>\n<h2>TypeScript Configuration<\/h2>\n<p>We need to configure Typescript for react-native to work. Create a config file named <em>tsconfig.json<\/em> using the <mark>tsc<\/mark> command.<\/p>\n<pre>tsc --init<\/pre>\n<p><em><strong>Note<\/strong>&#8211; To use the tsc command, you need to have Typescript installed globally.<\/em><\/p>\n<p>In order to build your React Native app with Typescript, change <em>App.js<\/em> to <em>App.tsx<\/em>.<\/p>\n<h2>Create Components<\/h2>\n<p>Let\u2019s get started with creating components for our application. Our basic Quiz application will consist of the following components- <\/p>\n<ul class=\"bullets text-left\">\n<li><strong>Screen<\/strong><\/li>\n<p>  \u27a1 Quiz.tsx<\/p>\n<li><strong>Components<\/strong><\/li>\n<p>  \u27a1 Headers.tsx<br \/>\n  \u27a1 Questions.tsx<br \/>\n  \u27a1 Answers.tsx<br \/>\n  \u27a1 Buttons.tsx<\/p>\n<li><strong>API Call<\/strong><\/li>\n<\/ul>\n<p>Now, we will go through each component file step by step and look into the code.<\/p>\n<h3>\/\/ Headers.tsx<\/h3>\n<pre>import React, {FC} from 'react';\r\nimport {SafeAreaView, StyleSheet, Text, StatusBar} from 'react-native';\r\n \r\ninterface Header {\r\n title: string;\r\n}\r\nconst HeaderClass: FC<Header> = props => {\r\n return (\r\n   < SafeAreaView >\r\n     < StatusBar backgroundColor=\"white\" \/ >\r\n     < Text style={styles.textstyle}>{props.title}< \/Text >\r\n   < \/SafeAreaView >\r\n );\r\n};\r\n \r\nconst styles = StyleSheet.create({\r\n textstyle: {\r\n   textAlign: 'center',\r\n   fontSize: 18,\r\n },\r\n} );\r\n \r\nexport default HeaderClass;<\/pre>\n<p><strong>Explanation:<\/strong><\/p>\n<pre>interface Header {\r\n title: string,\r\n}\r\nconst HeaderClass: FC<Header>=(props) => {\/*content*\/}<\/pre>\n<p>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, <strong>\u2018title\u2019<\/strong> with a specific type <strong>\u2018string.\u2019<\/strong> <\/p>\n<p>Here comes the benefit-  it gives us some validation when we use this component.<\/p>\n<p>Moreover, we have react native code which shows the text as header title with style defined to it.<\/p>\n<h3>>\/\/ Buttons.tsx<\/h3>\n<pre>import React, { FC } from 'react';\r\nimport { useEffect } from 'react';\r\nimport { SafeAreaView, StyleSheet, Text, TouchableOpacity} from 'react-native';\r\n \r\ninterface Title {\r\n key: number;\r\n answer: string;\r\n onPress: () = > void;\r\n correct: boolean;\r\n disabled: boolean;\r\n}\r\n \r\nconst Buttons: FC< Title > = props = > {\r\n useEffect(() => {}, []);\r\n return (\r\n   < SafeAreaView >\r\n     < TouchableOpacity\r\n       style={{\r\n         backgroundColor: !props.disabled ? '#F5F5DC' : '#F5DEB3',\r\n         width: '80%',\r\n         elevation: 5,\r\n         justifyContent: 'center',\r\n         alignContent: 'center',\r\n         marginLeft: 27,\r\n         height: 38,\r\n         marginTop: 10,\r\n       }}\r\n       onPress={() = > {\r\n         props.onPress();\r\n       }} >\r\n       < Text\r\n         style={[\r\n           styles.textstyle,\r\n           { color: props.correct ? 'brown' : 'black' },\r\n         ]} >\r\n         {props.answer}\r\n       < \/Text >\r\n     < \/TouchableOpacity >\r\n   < \/SafeAreaView >\r\n );\r\n};\r\n \r\nconst styles = StyleSheet.create \r\n{\r\n textstyle: {\r\n   textAlign: 'left',\r\n   fontSize: 17,\r\n   marginLeft: 8,\r\n },\r\n});\r\n \r\nexport default Buttons;<\/pre>\n<p>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.<\/p>\n<h3>\/\/ Answers.tsx<\/h3>\n<pre>import React, {FC} from 'react';\r\nimport { SafeAreaView, StyleSheet, View } from 'react-native';\r\nimport Buttons from '..\/components\/Buttons';\r\nimport { AnswerObject } from '..\/screens\/Quiz';\r\n \r\ninterface Answers {\r\n useranswer: AnswerObject | undefined;\r\n answers: string[];\r\n setcorrectanswer: any;\r\n checkanswer: () = > void;\r\n}\r\n \r\nconst Answers: FC<Answers > = props = > {\r\n return (\r\n   < SafeAreaView >\r\n     < View style = {{marginTop: 10, paddingHorizontal : 20 }} >\r\n       { props.answers.map ( (answer, key ) = > {\r\n         return (\r\n           < View key = {answer} >\r\n             < Buttons\r\n               {...{key, answer}}\r\n               correct={props.useranswer ?.correctanswer === answer}\r\n               disabled={props.useranswer ? true : false}\r\n               onPress={() = > {\r\n                 ( props.setcorrectanswer.current = answer),\r\n                   props.checkanswer( );\r\n               }} \r\n             \/ >\r\n           < \/View >\r\n         );\r\n       })}\r\n     < \/View >\r\n   < \/SafeAreaView >\r\n );\r\n};\r\n \r\nconst styles = StyleSheet.create({\r\n questioncontainer: {\r\n   flexDirection: 'row',\r\n   alignItems: 'center',\r\n   backgroundColor: 'white',\r\n   marginTop: 10,\r\n   paddingRight: 16,\r\n },\r\n \r\n textstyle: {padding: 15, fontSize: 15, color: 'blue' },\r\n} );\r\n \r\nexport default Answers;<\/pre>\n<p>In this file, we have an interface named Answers which defines an answer, useranswer, having another type interface <em>AnswerObject<\/em> (used in the class Quiz), <em>correctanswer<\/em>, <em>checkanswer<\/em> function. This file shows the multiple options below the question to choose from the prop of the child class. <\/p>\n<h3>\/\/ Question.tsx<\/h3>\n<pre>import React, {FC} from 'react';\r\nimport { SafeAreaView, StyleSheet, Text, View } from 'react-native';\r\n \r\ninterface Question {\r\n QuestionNo: number;\r\n Question: string;\r\n}\r\n \r\nconst Questions: FC<Question > = props = > {\r\n return (\r\n   < SafeAreaView >\r\n     < View style= { styles.questioncontainer } >\r\n       < Text style= { styles.textstyle} > { props.QuestionNo } < \/Text >\r\n       < Text\r\n         style = {{\r\n           fontSize :  15,\r\n           color :  'black',\r\n           textAlign :  'left',\r\n           marginRight :  7,\r\n         }} >\r\n         { props.Question }\r\n       < \/Text >\r\n     < \/View >\r\n   < \/SafeAreaView >\r\n );\r\n};\r\n \r\nconst styles = StyleSheet.create({\r\n questioncontainer: {\r\n   flexDirection: 'row',\r\n   alignItems: 'center',\r\n   backgroundColor: 'white',\r\n   marginTop: 10,\r\n   paddingRight: 16,\r\n },\r\n \r\n textstyle: {padding: 15, fontSize: 15, color: 'blue'},\r\n});\r\n \r\nexport default Questions;<\/pre>\n<p>In this file we have an interface named Question which defines props for QuestionNo and Question.<\/p>\n<h3>\/\/ Quiz.tsx<\/h3>\n<pre>import React, {FC, useEffect, useRef, useState} from 'react';\r\nimport {\r\n StyleSheet,\r\n Text,\r\n View,\r\n TouchableOpacity,\r\n ActivityIndicator,\r\n} from 'react-native';\r\nimport {getquestiojns, Question} from '..\/utils\/api';\r\nimport Questions from '..\/components\/Question';\r\nimport Answers from '..\/components\/Answers';\r\nimport {Icon} from 'react-native-elements';\r\n \r\nexport type AnswerObject = {\r\n question: string;\r\n answer: string;\r\n correct: boolean;\r\n correctanswer: string;\r\n};\r\n \r\nconst Quiz: FC = props = > {\r\n const [loader, setloader] = useState( false );\r\n const [question, setquestion] = useState<Question[ ] > ( [ ]);\r\n const [useranswers, setuseranswers] = useState<AnswerObject [] > ([]);\r\n const [score, setscore] = useState(0);\r\n const [ number, setnumber ] = useState(0);\r\n const [ totalquestion ] = useState(10);\r\n const [ gameover, setgameover ] = useState(true);\r\n const setcorrectanswer = useRef(null);\r\n const [ correcta, setcorrecta ] = useState('');\r\n \r\n useEffect( ( ) = > {\r\n   startQuiz( );\r\n }, [ ]);\r\n const startQuiz = async () = > {\r\n   setnumber( 0 );\r\n   setloader( true );\r\n   setgameover( false );\r\n   const newquestions = await getquestiojns();\r\n   console.log( newquestions );\r\n   setquestion( newquestions );\r\n   setscore( 0 );\r\n   setuseranswers( [] );\r\n   setloader( false );\r\n };\r\n const nextQuestion = ( ) = > {\r\n   const nextq = number + 1;\r\n   if ( nextq == totalquestion ) {\r\n     setgameover( true );\r\n   } else {\r\n     setnumber( nextq );\r\n   }\r\n };\r\n const checkanswer = ( ) = > {\r\n   if (!gameover) {\r\n     const answer = setcorrectanswer.current;\r\n \r\n     const correcta = question[ number ].correct_answer === answer;\r\n \r\n     if ( correcta ) setscore(prev = > prev + 1);\r\n \r\n     const answerobject = {\r\n       question: question [ number ].question,\r\n       answer,\r\n       correcta,\r\n       correctanswer: question[ number ].correct_answer,\r\n     };\r\n \r\n     setuseranswers ( prev = > [...prev, answerobject] );\r\n     setTimeout( ( ) = > {\r\n       nextQuestion( );\r\n     }, 1000);\r\n   }\r\n };\r\n \r\n return (\r\n   < View style = { { flex: 1 } } >\r\n     { !loader ? (\r\n       < View >\r\n         < View style ={ styles.container } >\r\n           < Text style = { styles.textstyle } > Questions< \/Text >\r\n           < Text style= { styles.textstyle } >\r\n             {number + 1} \/ { totalquestion }\r\n           < \/Text >\r\n         < \/View >\r\n         < View style ={ { marginLeft: 20 } } >\r\n           < Text style = {styles.textstyle} >Score : {score}< \/Text >\r\n         < \/View > \r\n         {question.length > 0 ? (\r\n           < >\r\n             < Questions\r\n               QuestionNo = { number + 1}\r\n               Question={question[number].question}\r\n             \/ >\r\n             < Answers\r\n               answers={question[ number ].answers }\r\n               {...{ setcorrectanswer, checkanswer } }\r\n               useranswer={ useranswers ? useranswers[ number] : undefined}\r\n             \/ >\r\n           < \/ >\r\n         ) : null}\r\n       < \/View >\r\n     ) : (\r\n       < ActivityIndicator\r\n         style={{justifyContent: 'center', top: 200}}\r\n         size={50}\r\n         color=\"black\"\r\n       \/ >\r\n     )}\r\n \r\n     < View >\r\n       { !gameover && !loader && number != totalquestion - 1 ? (\r\n         < TouchableOpacity onPress={ () = > nextQuestion( ) } >  \r\n           < Icon\r\n             name=\"arrowright\"\r\n             size={40}\r\n             color=\"black\"\r\n             type=\"antdesign\"\r\n             style={{left: 130, margin: 20}}\r\n           \/ >\r\n         < \/TouchableOpacity >\r\n       ) : number == totalquestion - 1 ? (\r\n         < TouchableOpacity onPress={() = > startQuiz() } >\r\n           < Icon\r\n             name=\"controller-play\"\r\n             size={40}\r\n             color=\"black\"\r\n             type=\"entypo\"\r\n             style={{left: 130, margin: 20}}\r\n           \/ >\r\n         < \/TouchableOpacity >\r\n       ) : null }\r\n     < \/View >\r\n   < \/View >\r\n );\r\n};\r\n \r\nconst styles = StyleSheet.create({\r\n container: {\r\n   flexDirection: 'row',\r\n   justifyContent: 'space-between',\r\n   marginTop: 70,\r\n   backgroundColor: 'white',\r\n },\r\n textstyle: {padding: 15, fontSize: 15, color: 'blue'},\r\n bottomview: {\r\n   padding: 13,\r\n   backgroundColor: 'blue',\r\n   borderRadius: 300,\r\n   width: 70,\r\n   height: 70,\r\n   position: 'absolute',\r\n   right: 20,\r\n   top: 550,\r\n },\r\n questioncontainer: {\r\n   flexDirection: 'row',\r\n   alignItems: 'center',\r\n   backgroundColor: 'white',\r\n   marginTop: 10,\r\n   paddingRight: 16,\r\n },\r\n iconstyle: {\r\n   backgroundColor: 'blue',\r\n   borderRadius: 50,\r\n   width: 70,\r\n   height: 70,\r\n   margin: 5,\r\n   top: 100,\r\n   left: 260,\r\n },\r\n} );\r\n \r\nexport default Quiz;<\/pre>\n<p>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.<\/p>\n<p>The answers class uses a function called checkanswer, which checks the current reference of the selected answer and checks it with the API\u2019s correct answer. If they match, then the score gets increased by one and proceeds to the next question.<\/p>\n<p class=\"boxed bg--secondary\" style=\"border: 1px solid #c7c7c7; box-shadow: 0 0 40px rgba(0, 0, 0, 0.2);\"><strong><i><span style=\"font-size:22px; color:#000;\">Want to leverage the advanced features of the New React Native Architecture?<\/span><br \/>\n<a href=\"https:\/\/www.bacancytechnology.com\/hire-react-native-developer\" target=\"_blank\" rel=\"noopener\">Hire React Native developer<\/a> from us who will bring the best of <a href=\"https:\/\/www.bacancytechnology.com\/blog\/react-native-ecosystem\" target=\"_blank\" rel=\"noopener\">React ecosystem<\/a> to outshine your cross-platform mobile application at the top<\/i><\/strong><\/p>\n<h3>\/\/ src\/utils\/api.tsx<\/h3>\n<pre>import axios from 'axios';\r\n \r\nexport const _ = (array: any[]) => [...array].sort(() => Math.random() - 0.7);\r\n \r\nexport type Question = {\r\n category: string;\r\n incorrect_answers: string[];\r\n correct_answer: string;\r\n difficulty: string;\r\n question: string;\r\n type: string;\r\n};\r\nexport const getquestiojns = async () = > {\r\n const endpoint = 'https:\/\/opentdb.com\/api.php?amount=10&category=9';\r\n const promise = await axios.get(endpoint);\r\n return promise.data.results.map((question: Question) = > ({\r\n   ...question,\r\n   answers: _([...question.incorrect_answers, question.correct_answer]),\r\n }));\r\n};<\/pre>\n<p>In this file, we have an interface named <em>Question<\/em>, 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.<\/p>\n<p>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 <a href=\"https:\/\/www.bacancytechnology.com\/react-native-app-development\">React Native app development company<\/a>. They will simplify the process and guide you through it. <\/p>\n<p>Also Read: <a href=\"https:\/\/www.bacancytechnology.com\/blog\/flexbox-layout-in-react-native\" target=\"_blank\" rel=\"noopener\">Understanding Flexbox Layout in React Native<\/a><\/p>\n<h2>Github Repository: React Native App with Typescript <\/h2>\n<p>You can visit here &#8211; <a href=\"https:\/\/github.com\/Vidushi-997\/react_native_typescript_quiz_example.git\" target=\"_blank\" rel=\"noopener\">Github Repository<\/a> and play around with code or follow the steps <em>React Native app with Typescript.<\/em><\/p>\n<h2>Conclusion<\/h2>\n<p>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 <a href=\"https:\/\/www.bacancytechnology.com\/tutorials\/react-native\">React Native tutorial<\/a> page. We have step-by-step instructions and guidelines regarding React Native development and source code for you to explore on your own.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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. Overview Typescript is a superset of Javascript that uses static typing, classes, and interfaces and is [&hellip;]<\/p>\n","protected":false},"author":170,"featured_media":21599,"comment_status":"open","ping_status":"open","sticky":false,"template":"blog-new-template.php","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"_lmt_disableupdate":"no","_lmt_disable":"","footnotes":""},"categories":[714],"tags":[],"coauthors":[2430],"class_list":["post-21585","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-react-native"],"acf":[],"modified_by":"Binal Prajapati","_links":{"self":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/21585","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/users\/170"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/comments?post=21585"}],"version-history":[{"count":0,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/posts\/21585\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media\/21599"}],"wp:attachment":[{"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/media?parent=21585"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/categories?post=21585"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/tags?post=21585"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/blog\/wp-json\/wp\/v2\/coauthors?post=21585"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}