使用 TypeScript 教程 React Native App
概述
Typescript 是 Javascript 的超集,它使用靜態(tài)類型、類、接口,因此被稱為面向?qū)ο蟮木幊陶Z言(OOP)。許多開發(fā)人員廣泛使用它來最大程度地減少錯(cuò)誤并在應(yīng)用程序中進(jìn)行類型檢查。添加嚴(yán)格類型使其成為更具自我表現(xiàn)力的代碼。由于嚴(yán)格的行為,有時(shí)開發(fā)人員發(fā)現(xiàn)很難在他們的項(xiàng)目中使用 TypeScript。
Typescript 代碼可以在任何瀏覽器、設(shè)備或操作系統(tǒng)上運(yùn)行。由于 TypeScript 是 Javascript 的超集,它會(huì)編譯成 Javascript,并且每個(gè)有效的 Javascript 都是有效的 Typescript。Typescript 在編譯時(shí)檢測(cè)錯(cuò)誤,因此在運(yùn)行時(shí)出現(xiàn)錯(cuò)誤的機(jī)會(huì)減少。Typescript 相對(duì)于 Javascript 的缺點(diǎn)在于它需要時(shí)間來完成代碼。
在本教程中,我們將學(xué)習(xí)使用 typescript 的 React Native 應(yīng)用程序,并了解如何構(gòu)建基本的 Quiz 應(yīng)用程序。
創(chuàng)建 React Native 應(yīng)用程序
最初,使用以下命令創(chuàng)建一個(gè) React Native 應(yīng)用程序。
反應(yīng)本機(jī)初始化 QuizAppcd 測(cè)驗(yàn)應(yīng)用程序
安裝依賴
使用以下命令安裝依賴項(xiàng)。
npm 安裝 typescript @types/react @types/react-native@types/react-test-renderer @types/jest
讓我們看看安裝的打字稿庫的用途。
打字稿:安裝打字稿
@types/react:為打字稿安裝反應(yīng)類型
@types/react-native:為打字稿安裝 React Native 類型
@types/react-test-renderer:為打字稿的測(cè)試渲染器安裝類型
@types/jest:安裝用于 typescript 的 jest 測(cè)試的類型
我們將需要 Axios 進(jìn)行 API 調(diào)用和代碼中使用的元素所需的庫。運(yùn)行以下命令。
npm 安裝 axios react-native-elements
打字稿配置
我們需要為 react-native 配置 Typescript 才能工作。使用以下命令創(chuàng)建一個(gè)名為tsconfig.json的配置文件TSC命令。
tsc--初始化
注意– 要使用 tsc 命令,您需要全局安裝 typescript。
為了使用打字稿構(gòu)建您的 React Native 應(yīng)用程序,請(qǐng)將App.js更改為App.tsx。
創(chuàng)建組件
讓我們開始為我們的應(yīng)用程序創(chuàng)建組件。我們的基本測(cè)驗(yàn)應(yīng)用程序?qū)韵陆M件 -
屏幕
成分
API調(diào)用
? 測(cè)驗(yàn).tsx
? Headers.tsx
? Questions.tsx
? Answers.tsx
? Buttons.tsx
現(xiàn)在,我們將逐步瀏覽每個(gè)組件文件并查看代碼。
// 標(biāo)題.tsx
從“反應(yīng)”中導(dǎo)入反應(yīng),{FC};從 'react-native' 導(dǎo)入 {SafeAreaView, StyleSheet, Text, StatusBar};
接口頭{
標(biāo)題:字符串;}const HeaderClass: FC<Header> = props => {
返回 (
<安全區(qū)域視圖>
<StatusBar backgroundColor="白色" />
<Text style={styles.textstyle}>{props.title}</Text>
</安全區(qū)域視圖>
);};
const styles = StyleSheet.create({
文本樣式:{
textAlign: '居中',
字體大?。?8,
},});
導(dǎo)出默認(rèn)的 HeaderClass;
解釋:
接口頭{
標(biāo)題:字符串,}const HeaderClass: FC<Header>=(props) => {/*內(nèi)容*/}
在 TypeScript 中,我們可以定義在組件中取什么以及如何取。在這里,我們聲明了一個(gè)名為 Header 的接口,它定義了 props 對(duì)象訪問組件的結(jié)構(gòu)。為此,定義 propsTo,具有特定類型“字符串”的“標(biāo)題”。
好處來了——當(dāng)我們使用這個(gè)組件時(shí),它給了我們一些驗(yàn)證。
此外,我們有反應(yīng)本機(jī)代碼,它將文本顯示為標(biāo)題標(biāo)題,并為其定義了樣式。
// 按鈕.tsx
從“反應(yīng)”中導(dǎo)入反應(yīng),{FC};從“反應(yīng)”中導(dǎo)入 {useEffect};從 'react-native' 導(dǎo)入 {SafeAreaView, StyleSheet, Text, TouchableOpacity};
界面標(biāo)題{
鍵:數(shù)字;
答案:字符串;
onPress: () => void;
正確:布爾值;
禁用:布爾值;}
常量按鈕:FC<Title> = props => {
useEffect(() => {}, []);
返回 (
<安全區(qū)域視圖>
<Touchable不透明度
樣式={{
backgroundColor: !props.disabled ?'#F5F5DC' : '#F5DEB3',
寬度:'80%',
海拔:5,
justifyContent: '中心',
對(duì)齊內(nèi)容:'中心',
左邊距:27,
身高:38,
保證金頂部:10,
}}
onPress={() => {
props.onPress();
}}>
<文字
風(fēng)格={[
樣式.textstyle,
{顏色:props.correct ? '棕黑色'},
]}>
{props.answer}
</文本>
</TouchableOpacity>
</安全區(qū)域視圖>
);};
const styles = StyleSheet.create({
文本樣式:{
textAlign: '左',
字體大小:17,
左邊距:8,
},});
導(dǎo)出默認(rèn)按鈕;
在文件 Buttons.tsx 中,我們有一個(gè)名為 Title 的接口,它包含 props 的結(jié)構(gòu)。它根據(jù)按下按鈕時(shí)的正確答案改變樣式,并根據(jù)從父類傳遞的道具禁用其他按鈕。
// 答案.tsx
從“反應(yīng)”中導(dǎo)入反應(yīng),{FC};從 'react-native' 導(dǎo)入 {SafeAreaView, StyleSheet, View};從 '../components/Buttons' 導(dǎo)入按鈕;從 '../screens/Quiz' 導(dǎo)入 {AnswerObject};
界面答案{
useranswer:AnswerObject | 不明確的;
答案:字符串[];
設(shè)置正確答案:任何;
檢查答案:()=>無效;}
常量答案:FC<Answers> = props => {
返回 (
<安全區(qū)域視圖>
<View style={{marginTop: 10, paddingHorizontal: 20}}>
{props.answers.map((answer, key) => {
返回 (
<查看鍵={answer}>
<按鈕
{...{鍵,答案}}
correct={props.useranswer?.correctanswer === answer}
禁用={props.useranswer ?真假}
onPress={() => {
(props.setcorrectanswer.current = 答案),
props.checkanswer();
}}
/>
</查看>
);
})}
</查看>
</安全區(qū)域視圖>
);};
const styles = StyleSheet.create({
問題容器:{
flexDirection: '行',
alignItems: '中心',
背景顏色:'白色',
保證金頂部:10,
填充右:16,
},
textstyle: {padding: 15, fontSize: 15, color: 'blue'},});
導(dǎo)出默認(rèn)答案;
在這個(gè)文件中,我們有一個(gè)名為 Answers 的接口,它定義了一個(gè)答案,useranswer,具有另一種類型的接口 AnswerObject (在類 Quiz 中使用)、correctanswer、checkanswer函數(shù)。該文件顯示了問題下方的多個(gè)選項(xiàng),以從子類的 prop 中進(jìn)行選擇。
// 問題.tsx
從“反應(yīng)”中導(dǎo)入反應(yīng),{FC};從 'react-native' 導(dǎo)入 {SafeAreaView, StyleSheet, Text, View};
接口問題{
問題編號(hào):編號(hào);
問題:字符串;}
常量問題:FC<Question> = props => {
返回 (
<安全區(qū)域視圖>
<查看樣式={styles.questioncontainer}>
<Text style={styles.textstyle}>{props.QuestionNo}</Text>
<文字
樣式={{
字體大?。?5,
顏色:黑色',
textAlign: '左',
右邊距:7,
}}>
{道具.問題}
</文本>
</查看>
</安全區(qū)域視圖>
);};
const styles = StyleSheet.create({
問題容器:{
flexDirection: '行',
alignItems: '中心',
背景顏色:'白色',
保證金頂部:10,
填充右:16,
},
textstyle: {padding: 15, fontSize: 15, color: 'blue'},});
導(dǎo)出默認(rèn)問題;
在這個(gè)文件中,我們有一個(gè)名為 Question 的接口,它定義了 QuestionNo 和 Question 的屬性。
// 測(cè)驗(yàn).tsx
從'react'導(dǎo)入React,{FC,useEffect,useRef,useState};進(jìn)口 {
樣式表,
文本,
看法,
可觸摸的不透明度,
活動(dòng)指示器,} 來自“本機(jī)反應(yīng)”;從'../utils/api'導(dǎo)入{getquestiojns,問題};從'../components/Question'導(dǎo)入問題;從'../components/Answers'導(dǎo)入答案;從'react-native-elements'導(dǎo)入{Icon};
導(dǎo)出類型 AnswerObject = {
問題:字符串;
答案:字符串;
正確:布爾值;
正確答案:字符串;};
const 測(cè)驗(yàn):FC = props => {
const [loader, setloader] = useState(false);
const [question, setquestion] = useState<Question[]>([]);
const [useranswers, setuseranswers] = useState<AnswerObject[]>([]);
const [分?jǐn)?shù), 設(shè)置分?jǐn)?shù)] = useState(0);
const [number, setnumber] = useState(0);
const [totalquestion] = useState(10);
const [gameover, setgameover] = useState(true);
const setcorrectanswer = useRef(null);
const [correcta, setcorrecta] = useState('');
使用效果(()=> {
開始測(cè)驗(yàn)();
}, []);
const startQuiz = async () => {
設(shè)定數(shù)(0);
設(shè)置加載器(真);
設(shè)置游戲結(jié)束(假);
const newquestions = await getquestiojns();
控制臺(tái)日志(新問題);
設(shè)置問題(新問題);
設(shè)置分?jǐn)?shù)(0);
設(shè)置用戶答案([]);
設(shè)置加載器(假);
};
const nextQuestion = () => {
const nextq = 數(shù)字 + 1;
如果(nextq == totalquestion){
設(shè)置游戲結(jié)束(真);
} 別的 {
設(shè)置編號(hào)(下一個(gè));
}
};
const checkanswer = () => {
如果(!游戲結(jié)束){
const answer = setcorrectanswer.current;
const correcta = 問題[數(shù)字].correct_answer === 答案;
如果 (correcta) setscore(prev => prev + 1);
const answerobject = {
問題:?jiǎn)栴}[數(shù)字].問題,
回答,
更正,
正確答案:?jiǎn)栴}[數(shù)字].correct_answer,
};
setuseranswers(prev => [...prev, answerobject]);
設(shè)置超時(shí)(()=> {
下一個(gè)問題();
}, 1000);
}
};
返回 (
<視圖樣式={{flex: 1}}>
{!裝載機(jī)?(
<視圖>
<查看樣式={styles.container}>
<Text style={styles.textstyle}>問題</Text>
<文本樣式={styles.textstyle}>
{number + 1}/{totalquestion}
</文本>
</查看>
<視圖樣式={{marginLeft: 20}}>
<Text style={styles.textstyle}>分?jǐn)?shù):{score}</Text>
</查看>
{question.length > 0 ? (
<>
<問題
問題編號(hào)={數(shù)字+1}
問題={問題[數(shù)字].問題}
/>
<答案
答案={問題[數(shù)字].答案}
{...{setcorrectanswer, checkanswer}}
useranswer={用戶答案?useranswers[number] : undefined}
/>
</>
) : 無效的}
</查看>
) : (
<活動(dòng)指示器
style={{justifyContent: 'center', top: 200}}
尺寸={50}
顏色=“黑色”
/>
)}
<視圖>
{!gameover && !loader && number != totalquestion - 1 ? (
<TouchableOpacity onPress={() => nextQuestion()}>
<圖標(biāo)
名稱=“右箭頭”
尺寸={40}
顏色=“黑色”
類型=“螞蟻設(shè)計(jì)”
樣式={{左:130,邊距:20}}
/>
</TouchableOpacity>
) : number == totalquestion - 1 ? (
<TouchableOpacity onPress={() => startQuiz()}>
<圖標(biāo)
名稱=“控制器播放”
尺寸={40}
顏色=“黑色”
類型=“輸入錯(cuò)誤”
樣式={{左:130,邊距:20}}
/>
</TouchableOpacity>
) : 無效的}
</查看>
</查看>
);};
const styles = StyleSheet.create({
容器: {
flexDirection: '行',
justifyContent: '空格',
保證金頂部:70,
背景顏色:'白色',
},
textstyle: {padding: 15, fontSize: 15, color: 'blue'},
底視圖:{
填充:13,
背景顏色:'藍(lán)色',
邊界半徑:300,
寬度:70,
身高:70,
位置:'絕對(duì)',
右:20,
頂部:550,
},
問題容器:{
flexDirection: '行',
alignItems: '中心',
背景顏色:'白色',
保證金頂部:10,
填充右:16,
},
圖標(biāo)樣式:{
背景顏色:'藍(lán)色',
邊界半徑:50,
寬度:70,
身高:70,
保證金:5,
頂部:100,
左:260,
},});
導(dǎo)出默認(rèn)測(cè)驗(yàn);
這是加載時(shí)顯示的主屏幕。當(dāng)屏幕呈現(xiàn)時(shí),它會(huì)將所有狀態(tài)設(shè)置為初始階段,并調(diào)用 API 來設(shè)置要顯示的問題和選項(xiàng)。當(dāng) API 返回?cái)?shù)據(jù)時(shí),會(huì)調(diào)用 Question 和 Answers 類以在 props 的幫助下呈現(xiàn)項(xiàng)目。
answers 類使用一個(gè)名為 checkanswer 的函數(shù),該函數(shù)檢查所選答案的當(dāng)前引用并將其與 API 的正確答案進(jìn)行核對(duì)。如果它們匹配,則分?jǐn)?shù)增加 1 并繼續(xù)下一個(gè)問題。
想要利用 New React Native Architecture 的高級(jí)功能?
聘請(qǐng)我們的 React Native 開發(fā)人員,他們將帶來最好的 React 生態(tài)系統(tǒng),讓您的跨平臺(tái)移動(dòng)應(yīng)用程序脫穎而出。
// src/utils/api.tsx
從“axios”導(dǎo)入 axios;
export const _ = (array: any[]) => [...array].sort(() => Math.random() - 0.7);
導(dǎo)出類型問題 = {
類別:字符串;
不正確的答案:字符串[];
正確答案:字符串;
難度:字符串;
問題:字符串;
類型:字符串;};export const getquestiojns = async () => {
const endpoint = 'https://opentdb.com/api.php?amount=10&category=9';
const promise = await axios.get(endpoint);
返回 promise.data.results.map((問題:?jiǎn)栴}) => ({
...問題,
答案:_([...question.incorrect_answers, question.correct_answer]),
}));};
在這個(gè)文件中,我們有一個(gè)名為Question的接口,它有一個(gè)結(jié)構(gòu)用作 props 來返回這個(gè) Quiz App 中的所需選項(xiàng)。它使用 Axios 庫從 API 獲取詳細(xì)信息。它返回來自 API 的結(jié)果,其中包含基于多個(gè)選項(xiàng)的問題和答案。
Github 存儲(chǔ)庫:React Native App with Typescript
您可以訪問此處 - Github 存儲(chǔ)庫并使用代碼或按照上述步驟使用 Typescript 開發(fā) React Native 應(yīng)用程序。
結(jié)論
所以,這一切都是關(guān)于使用 Typescript 構(gòu)建一個(gè)基本的 React Native 應(yīng)用程序。一個(gè)簡(jiǎn)單的測(cè)驗(yàn)應(yīng)用程序流程,可以更好地理解 TypeScript 在 React Native 中的工作原理。我希望你登陸本教程的目的已經(jīng)實(shí)現(xiàn)。如需更多此類教程,請(qǐng)隨時(shí)訪問React Native 教程頁面。我們有包含基本和高級(jí) React Native 知識(shí)的分步指南;我們還提供源代碼供您自行探索。