使用 TypeScript 教程 React Native App

言鼎科技 2023-06-28 347

概述

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件 -

  • 屏幕

  • ? 測(cè)驗(yàn).tsx

  • 成分

  • ? Headers.tsx
    ? Questions.tsx
    ? Answers.tsx
    ? Buttons.tsx

  • API調(diào)用

現(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 中使用)、correctanswercheckanswer函數(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)的問題和答案。

另請(qǐng)閱讀

了解 React Native 中的 Flexbox 布局

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í)的分步指南;我們還提供源代碼供您自行探索。

言鼎科技

The End