使用 TypeScript 教程 React Native App

言鼎科技 2023-06-28 195

概述

Typescript 是 Javascript 的超集,它使用静态类型、类、接口,因此被称为面向对象的编程语言(OOP)。许多开发人员广泛使用它来最大程度地减少错误并在应用程序中进行类型检查。添加严格类型使其成为更具自我表现力的代码。由于严格的行为,有时开发人员发现很难在他们的项目中使用 TypeScript。

Typescript 代码可以在任何浏览器、设备或操作系统上运行。由于 TypeScript 是 Javascript 的超集,它会编译成 Javascript,并且每个有效的 Javascript 都是有效的 Typescript。Typescript 在编译时检测错误,因此在运行时出现错误的机会减少。Typescript 相对于 Javascript 的缺点在于它需要时间来完成代码。

在本教程中,我们将学习使用 typescript 的 React Native 应用程序,并了解如何构建基本的 Quiz 应用程序。

创建 React Native 应用程序

最初,使用以下命令创建一个 React Native 应用程序。


反应本机初始化 QuizAppcd 测验应用程序

安装依赖

使用以下命令安装依赖项。


npm 安装 typescript @types/react @types/react-native@types/react-test-renderer @types/jest

让我们看看安装的打字稿库的用途。

  • 打字稿:安装打字稿

  • @types/react:为打字稿安装反应类型

  • @types/react-native:为打字稿安装 React Native 类型

  • @types/react-test-renderer:为打字稿的测试渲染器安装类型

  • @types/jest:安装用于 typescript 的 jest 测试的类型

我们将需要 Axios 进行 API 调用和代码中使用的元素所需的库。运行以下命令。


npm 安装 axios react-native-elements

打字稿配置

我们需要为 react-native 配置 Typescript 才能工作。使用以下命令创建一个名为tsconfig.json的配置文件TSC命令。


tsc--初始化

注意– 要使用 tsc 命令,您需要全局安装 typescript。

为了使用打字稿构建您的 React Native 应用程序,请将App.js更改为App.tsx

创建组件

让我们开始为我们的应用程序创建组件。我们的基本测验应用程序将包含以下组件 -

  • 屏幕

  • ➡ 测验.tsx

  • 成分

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

  • API调用

现在,我们将逐步浏览每个组件文件并查看代码。

// 标题.tsx


从“反应”中导入反应,{FC};从 'react-native' 导入 {SafeAreaView, StyleSheet, Text, StatusBar};
接口头{
标题:字符串;}const HeaderClass: FC<Header> = props => {
返回 (
  <安全区域视图>
    <StatusBar backgroundColor="白色" />
    <Text style={styles.textstyle}>{props.title}</Text>
  </安全区域视图>
);};
const styles = StyleSheet.create({
文本样式:{
  textAlign: '居中',
  字体大小:18,
},});
导出默认的 HeaderClass;

解释:


接口头{
标题:字符串,}const HeaderClass: FC<Header>=(props) => {/*内容*/}

在 TypeScript 中,我们可以定义在组件中取什么以及如何取。在这里,我们声明了一个名为 Header 的接口,它定义了 props 对象访问组件的结构。为此,定义 propsTo,具有特定类型“字符串”的“标题”。

好处来了——当我们使用这个组件时,它给了我们一些验证。

此外,我们有反应本机代码,它将文本显示为标题标题,并为其定义了样式。

// 按钮.tsx


从“反应”中导入反应,{FC};从“反应”中导入 {useEffect};从 'react-native' 导入 {SafeAreaView, StyleSheet, Text, TouchableOpacity};
界面标题{
键:数字;
答案:字符串;
onPress: () => void;
正确:布尔值;
禁用:布尔值;}
常量按钮:FC<Title> = props => {
useEffect(() => {}, []);
返回 (
  <安全区域视图>
    <Touchable不透明度
      样式={{
        backgroundColor: !props.disabled ?'#F5F5DC' : '#F5DEB3',
        宽度:'80%',
        海拔:5,
        justifyContent: '中心',
        对齐内容:'中心',
        左边距:27,
        身高:38,
        保证金顶部:10,
      }}
      onPress={() => {
        props.onPress();
      }}>
      <文字
        风格={[
          样式.textstyle,
          {颜色:props.correct ? '棕黑色'},
        ]}>
        {props.answer}
      </文本>
    </TouchableOpacity>
  </安全区域视图>
);};
const styles = StyleSheet.create({
文本样式:{
  textAlign: '左',
  字体大小:17,
  左边距:8,
},});
导出默认按钮;

在文件 Buttons.tsx 中,我们有一个名为 Title 的接口,它包含 props 的结构。它根据按下按钮时的正确答案改变样式,并根据从父类传递的道具禁用其他按钮。

// 答案.tsx


从“反应”中导入反应,{FC};从 'react-native' 导入 {SafeAreaView, StyleSheet, View};从 '../components/Buttons' 导入按钮;从 '../screens/Quiz' 导入 {AnswerObject};
界面答案{
useranswer:AnswerObject | 不明确的;
答案:字符串[];
设置正确答案:任何;
检查答案:()=>无效;}
常量答案:FC<Answers> = props => {
返回 (
  <安全区域视图>
    <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();
              }}
            />
          </查看>
        );
      })}
    </查看>
  </安全区域视图>
);};
const styles = StyleSheet.create({
问题容器:{
  flexDirection: '行',
  alignItems: '中心',
  背景颜色:'白色',
  保证金顶部:10,
  填充右:16,
},

textstyle: {padding: 15, fontSize: 15, color: 'blue'},});
导出默认答案;

在这个文件中,我们有一个名为 Answers 的接口,它定义了一个答案,useranswer,具有另一种类型的接口 AnswerObject 在类 Quiz 中使用)、correctanswercheckanswer函数。该文件显示了问题下方的多个选项,以从子类的 prop 中进行选择。

// 问题.tsx


从“反应”中导入反应,{FC};从 'react-native' 导入 {SafeAreaView, StyleSheet, Text, View};
接口问题{
问题编号:编号;
问题:字符串;}
常量问题:FC<Question> = props => {
返回 (
  <安全区域视图>
    <查看样式={styles.questioncontainer}>
      <Text style={styles.textstyle}>{props.QuestionNo}</Text>
      <文字
        样式={{
          字体大小:15,
          颜色:黑色',
          textAlign: '左',
          右边距:7,
        }}>
        {道具.问题}
      </文本>
    </查看>
  </安全区域视图>
);};
const styles = StyleSheet.create({
问题容器:{
  flexDirection: '行',
  alignItems: '中心',
  背景颜色:'白色',
  保证金顶部:10,
  填充右:16,
},

textstyle: {padding: 15, fontSize: 15, color: 'blue'},});
导出默认问题;

在这个文件中,我们有一个名为 Question 的接口,它定义了 QuestionNo 和 Question 的属性。

// 测验.tsx


从'react'导入React,{FC,useEffect,useRef,useState};进口 {
样式表,
文本,
看法,
可触摸的不透明度,
活动指示器,} 来自“本机反应”;从'../utils/api'导入{getquestiojns,问题};从'../components/Question'导入问题;从'../components/Answers'导入答案;从'react-native-elements'导入{Icon};
导出类型 AnswerObject = {
问题:字符串;
答案:字符串;
正确:布尔值;
正确答案:字符串;};
const 测验:FC = props => {
const [loader, setloader] = useState(false);
const [question, setquestion] = useState<Question[]>([]);
const [useranswers, setuseranswers] = useState<AnswerObject[]>([]);
const [分数, 设置分数] = useState(0);
const [number, setnumber] = useState(0);
const [totalquestion] = useState(10);
const [gameover, setgameover] = useState(true);
const setcorrectanswer = useRef(null);
const [correcta, setcorrecta] = useState('');

使用效果(()=> {
  开始测验();
}, []);
const startQuiz = async () => {
  设定数(0);
  设置加载器(真);
  设置游戏结束(假);
  const newquestions = await getquestiojns();
  控制台日志(新问题);
  设置问题(新问题);
  设置分数(0);
  设置用户答案([]);
  设置加载器(假);
};
const nextQuestion = () => {
  const nextq = 数字 + 1;
  如果(nextq == totalquestion){
    设置游戏结束(真);
  } 别的 {
    设置编号(下一个);
  }
};
const checkanswer = () => {
  如果(!游戏结束){
    const answer = setcorrectanswer.current;

    const correcta = 问题[数字].correct_answer === 答案;

    如果 (correcta) setscore(prev => prev + 1);

    const answerobject = {
      问题:问题[数字].问题,
      回答,
      更正,
      正确答案:问题[数字].correct_answer,
    };

    setuseranswers(prev => [...prev, answerobject]);
    设置超时(()=> {
      下一个问题();
    }, 1000);
  }
};

返回 (
  <视图样式={{flex: 1}}>
    {!装载机?(
      <视图>
        <查看样式={styles.container}>
          <Text style={styles.textstyle}>问题</Text>
          <文本样式={styles.textstyle}>
            {number + 1}/{totalquestion}
          </文本>
        </查看>
        <视图样式={{marginLeft: 20}}>
          <Text style={styles.textstyle}>分数:{score}</Text>
        </查看>
        {question.length > 0 ? (
          <>
            <问题
              问题编号={数字+1}
              问题={问题[数字].问题}
            />
            <答案
              答案={问题[数字].答案}
              {...{setcorrectanswer, checkanswer}}
              useranswer={用户答案?useranswers[number] : undefined}
            />
          </>
        ) : 无效的}
      </查看>
    ) : (
      <活动指示器
        style={{justifyContent: 'center', top: 200}}
        尺寸={50}
        颜色=“黑色”
      />
    )}

    <视图>
      {!gameover && !loader && number != totalquestion - 1 ? (
        <TouchableOpacity onPress={() => nextQuestion()}>
          <图标
            名称=“右箭头”
            尺寸={40}
            颜色=“黑色”
            类型=“蚂蚁设计”
            样式={{左:130,边距:20}}
          />
        </TouchableOpacity>
      ) : number == totalquestion - 1 ? (
        <TouchableOpacity onPress={() => startQuiz()}>
          <图标
            名称=“控制器播放”
            尺寸={40}
            颜色=“黑色”
            类型=“输入错误”
            样式={{左:130,边距:20}}
          />
        </TouchableOpacity>
      ) : 无效的}
    </查看>
  </查看>
);};
const styles = StyleSheet.create({
容器: {
  flexDirection: '行',
  justifyContent: '空格',
  保证金顶部:70,
  背景颜色:'白色',
},
textstyle: {padding: 15, fontSize: 15, color: 'blue'},
底视图:{
  填充:13,
  背景颜色:'蓝色',
  边界半径:300,
  宽度:70,
  身高:70,
  位置:'绝对',
  右:20,
  顶部:550,
},
问题容器:{
  flexDirection: '行',
  alignItems: '中心',
  背景颜色:'白色',
  保证金顶部:10,
  填充右:16,
},
图标样式:{
  背景颜色:'蓝色',
  边界半径:50,
  宽度:70,
  身高:70,
  保证金:5,
  顶部:100,
  左:260,
},});
导出默认测验;

这是加载时显示的主屏幕。当屏幕呈现时,它会将所有状态设置为初始阶段,并调用 API 来设置要显示的问题和选项。当 API 返回数据时,会调用 Question 和 Answers 类以在 props 的帮助下呈现项目。

answers 类使用一个名为 checkanswer 的函数,该函数检查所选答案的当前引用并将其与 API 的正确答案进行核对。如果它们匹配,则分数增加 1 并继续下一个问题。

想要利用 New React Native Architecture 的高级功能?
聘请我们的 React Native 开发人员,他们将带来最好的 React 生态系统,让您的跨平台移动应用程序脱颖而出。

// src/utils/api.tsx


从“axios”导入 axios;
export const _ = (array: any[]) => [...array].sort(() => Math.random() - 0.7);
导出类型问题 = {
类别:字符串;
不正确的答案:字符串[];
正确答案:字符串;
难度:字符串;
问题:字符串;
类型:字符串;};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((问题:问题) => ({
  ...问题,
  答案:_([...question.incorrect_answers, question.correct_answer]),
}));};

在这个文件中,我们有一个名为Question的接口,它有一个结构用作 props 来返回这个 Quiz App 中的所需选项。它使用 Axios 库从 API 获取详细信息。它返回来自 API 的结果,其中包含基于多个选项的问题和答案。

另请阅读

了解 React Native 中的 Flexbox 布局

Github 存储库:React Native App with Typescript

您可以访问此处 - Github 存储库并使用代码或按照上述步骤使用 Typescript 开发 React Native 应用程序。

结论

所以,这一切都是关于使用 Typescript 构建一个基本的 React Native 应用程序。一个简单的测验应用程序流程,可以更好地理解 TypeScript 在 React Native 中的工作原理。我希望你登陆本教程的目的已经实现。如需更多此类教程,请随时访问React Native 教程页面。我们有包含基本和高级 React Native 知识的分步指南;我们还提供源代码供您自行探索。

言鼎科技

The End