Typescript结合React实践

2023-10-27

作者:慕晨同学

原文地址:https://juejin.im/post/5d37b5d9f265da1bd605e5e1

写在前面

Typescript是JavaScript的一个超集,主要提供了类型系统和对es6的支持。本人使用ts编写react将近3个月的时间,中间踩了不少坑,从刚开始的觉得ts没有必要到现在觉得ts真香。在这里对使用ts编写react的心得做一下总结。

本文将从以下几部分进行总结:

  1. Typescript的优势

  2. TS结合React使用

  3. 总结

  4. 参考链接及扩展阅读

Typescript的优势

1.帮助更好地重构代码

一个好的代码习惯是常常对自己写的代码进行小的重构,使得代码可维护性更强。但是对于很多线上运行的代码,代码测试覆盖率往往不是很高,有时候哪怕一个变量名的改动,都会牵一发而动全身。而对于使用ts编写的项目就不会有这种担心。ts的静态检查特性会帮助找出代码中有错误的部分。

2.vscode等IDE的提示更加智能

js是一门动态弱类型解释语言,变量声明后可以改变类型,而且类型需要在运行时才能确定。而ts的报错提示是在编译时,不是在运行时。所以使用ts带来的静态类型检查等特性将使得IDE的提示更加完善。

3.类型声明本身就是非常好的文档

当你接手一个有历史包袱的项目时,肯定会头疼于文档和代码注释的缺失,而对于ts来说,是可以做到代码即文档的,通过声明文件可以知道哪些字段的含义以及哪些字段是必填和选填的。举个简单例子,当封装一个button的组件时:


export interface ButtonProps {
  style?: React.CSSProperties
  className?: string
  label?: React.ReactNode
  type?: 'primary' | 'default' | 'search'
  size?: 'sm' | 'md' | 'lg' | 'mini'
  disabled?: boolean
  title?: string
  onClick?: ((e: React.MouseEvent<HTMLButtonElement>) => void)
}

通过这些声明文件可以知道,当使用这个button文件时,style是一个可选值,表示一个可以自定义样式的style字段。type也是一个可选值,表示按钮的颜色类型,可以选择'primary','default','mini'其中的一种。disabled也是一个可选值,传入的值必须是boolean类型。所以就可以看出类型声明本身就是非常好的文档。

TS结合React使用

类组件的使用

以下是官网的一个例子,创建Props和State接口,Props接口接受name和enthusiasmLevel参数,State接口接受currentEnthusiasm参数。

import * as React from "react";

export interface Props {
  name: string;
  enthusiasmLevel?: number;
}

interface State {
  currentEnthusiasm: number;
}

class Hello extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { currentEnthusiasm: props.enthusiasmLevel || 1 };
  }

  onIncrement = () => this.updateEnthusiasm(this.state.currentEnthusiasm + 1);
  onDecrement = () => this.updateEnthusiasm(this.state.currentEnthusiasm - 1);

  render() {
    const { name } = this.props;

    if (this.state.currentEnthusiasm <= 0) {
      throw new Error('You could be a little more enthusiastic. :D');
    }

    return (
      <div className="hello">
        <div className="greeting">
          Hello {name + getExclamationMarks(this.state.currentEnthusiasm)}
        </div>
        <button onClick={this.onDecrement}>-</button>
        <button onClick={this.onIncrement}>+</button>
      </div>
    );
  }

  updateEnthusiasm(currentEnthusiasm: number) {
    this.setState({ currentEnthusiasm });
  }
}

export default Hello;

function getExclamationMarks(numChars: number) {
  return Array(numChars + 1).join('!');
}

无状态组件的使用

无状态组件也称为傻瓜组件,如果一个组件内部没有自身的state,那么组件就可以称为无状态组件。在@types/react已经定义了一个类型type SFC<P = {}> = StatelessComponent

。我们写无状态组件的时候,能指定我们的组件为SFC或StatelessComponent。它已经预定义了children,displayName等。以button为例:

import React from 'react'

const Button = ({ onClick: handleClick, children }) => (
  <button onClick={handleClick}>{children}</button>
)

如果采用ts来编写出来的无状态组件是这样的:

import React, { MouseEvent, SFC } from 'react';

type Props = { onClick(e: MouseEvent<HTMLElement>): void };

const Button: SFC<Props> = ({ onClick: handleClick, children }) => (
  <button onClick={handleClick}>{children}</button>
);

readonly

react规定不能通过this.props.xxx和this.state.xxx直接进行修改,所以可以将State和Props标记为不可变数据:

interface Props {
  readonly number: number;
}

interface State {
  readonly color: string;
}

export class Hello extends React.Component<Props, State> {
  someMethod() {
    this.props.number = 123; // Error: props 是不可变的
    this.state.color = 'red'; // Error: 你应该使用 this.setState()
  }
}

处理Event对象

在工作中,可能经常会使用Event对象,change事件可以使用React.ChangeEvent, click事件可以使用React.ChangeEvent。

  onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
      // do something
  }

  onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      // do something
  }

可渲染的接口

React 可以渲染一些像 JSX 或者是 string 的内容,这些被合并到类型 React.ReactNode 中,因此,当你接收可渲染的内容时,你可以使用它:

type Props = {
  header: React.ReactNode;
  body: React.ReactNode;
};

class MyComonent extends React.Component<Props, {}> {
  render() {
    return (
      <div>
        {this.props.header}
        {this.props.body}
      </div>
    );
  }
}

<MyComponent header={<h1>Header</h1>} body={<i>body</i>} />

总结

在大中型前端项目中,由于js的动态弱类型特性,导致很多错误在运行时才发现。ts作为js的超集,为前端开发带来了编译时的检查,将很多的错误避免在了编译阶段。也为IDE带来了更强的智能提示。虽然学习ts会花一些时间,但这些时间是值得的。使用ts开发项目之后,明显发现项目的可维护性变强了,bug率降低了,查文档也更加方便,一看类型声明文件就明白了各个字段的含义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Typescript结合React实践 的相关文章

  • 仅一页 JavaScript 应用程序

    您是否尝试过单页 Web 应用程序 即浏览器仅从服务器 获取 一页 其余部分由客户端 JavaScript 代码处理 此类 应用程序页面 的一个很好的例子是 Gmail 对于更简单的应用程序 例如博客和 CMS 使用这种方法有哪些优点和缺点
  • 如何将 Jfreechart(饼图)添加到 netbeans 的面板中

    我正在使用 netbeans gui 编辑器 并且正在尝试添加一个本身位于内部框架中的 Jfreechart 并且这个内部框架我想将其添加到面板中 正如您在此图中看到的那样 抱歉 我无法直接发布图像 因为我新手 http www flick
  • Cloudfoundry:如何组合两个运行时

    cloundfoundry 有没有办法结合两个运行时环境 我正在将 NodeJS 应用程序部署到 IBM Bluemix 现在 我还希望能够执行独立的 jar 文件 但应用程序失败 APP 0 bin sh 1 java not found
  • Google Chrome 106 可拖动导致元素消失

    使用拖放元素时 绝对定位元素中包含的大多数其他元素都会从屏幕上消失 如果我调整窗口大小 这些元素会出现 但在开始拖动时会再次消失 我在最新版本的 Google Chrome 106 和 Beta 版本 107 0 5304 18 以及现在的
  • 如何在 Eclipse Java 动态 Web 项目中使用 .properties 文件?

    我正在 Eclipse 中开发动态 Web 项目 我创建了一个 properties 文件来存储数据库详细信息 用户名 密码等 我通过右键单击项目和 New gt File 添加它 我使用了Java util包Properties类 但它不
  • 尝试使用等于“是”或“否”的字符串变量重新启动 do-while 循环

    计算行程距离的非常简单的程序 一周前刚刚开始 我有这个循环用于解决真或假问题 但我希望它适用于简单的 是 或 否 我为此分配的字符串是答案 public class Main public static void main String a
  • 如何使JavaScript函数在Eclipse“大纲视图”中可见?

    我有这样的代码 但如果它在匿名函数中定义 则无法打开函数大纲 类没有问题 我该如何概述something2 请分享一些提示 我可以将所有函数标记为构造函数 但这是无效的方法 start of track event required deb
  • 将图像添加到自定义 AlertDialog

    我制作了一个 AlertDialog 让用户可以从我显示的 4 个选项中选择一个 前 3 个让他们在单击号码时直接拨打号码 第 4 个显示不同的视图 现在看起来是这样的 由于第四个选项的目的是不同的任务 我想让它看起来不同 因为用户可能会感
  • 如何在 Quartz 调度程序中每 25 秒运行一次?

    我正在使用 Java 的 Quartz Scheduling API 你能帮我使用 cron 表达式每 25 秒运行一次吗 这只是一个延迟 它不必总是从第 0 秒开始 例如 序列如下 0 00 0 25 0 50 1 15 1 40 2 0
  • JVM:是否可以操作帧堆栈?

    假设我需要执行N同一线程中的任务 这些任务有时可能需要来自外部存储的一些值 我事先不知道哪个任务可能需要这样的值以及何时 获取速度要快得多M价值观是一次性的而不是相同的M值在M查询外部存储 注意我不能指望任务本身进行合作 它们只不过是 ja
  • Java:拆箱整数时出现空指针异常?

    此代码导致空指针异常 我不知道为什么 private void setSiblings PhylogenyTree node Color color throws InvalidCellNumberException PhylogenyTr
  • 类型“typeof import("/home/kartik/Desktop/Ecommerce/ecommerce/node_modules/firebase/index")”上不存在属性“auth”。 TS(2339)

    我是 FireBase 的初学者 我正在尝试使用 Angular 通过 FireBase 实现 Google 登录 我在 auth 时收到上述错误 我特此附上login component ts和package json package l
  • 为什么“tbody”不设置表格的背景颜色?

    我在用 tbody 作为 CSS 选择器来设置background color在一个表中 我这样做是因为我有多个 tbody 表内的部分 它们具有不同的背景颜色 我的问题是 当使用border radius在细胞上 细胞不尊重backgro
  • 挂钩 Eclipse 构建过程吗?

    我希望在 Eclipse 中按下构建按钮时能够运行一个简单的 Java 程序 目前 当我单击 构建 时 它会运行一些 JRebel 日志记录代码 我有一个程序可以解析 JRebel 日志文件并将统计信息存储在数据库中 是否可以编写一个插件或
  • 查询为空 Node Js Sequelize

    我正在尝试更新 Node js 应用程序中的数据 我和邮递员测试过 我的开发步骤是 从数据库 MySQL 获取ID为10的数据进行更新 gt gt 未处理的拒绝SequelizeDatabaseError 查询为空 我认识到 我使用了错误的
  • JavaScript 代码在不使用 ActiveX 的情况下截取网站屏幕截图

    我有一个用户与之交互的 JavaScript 应用程序 我需要保存当前界面的外观 裁剪出我需要的部分 或者通过指定div只拍摄我需要的部分 然后发送回服务器 显然任何外部服务都无法做到这一点 我需要一个 JavaScript 或Flash
  • Hibernate 和可序列化实体

    有谁知道是否有一个框架能够从实体类中剥离 Hibernate 集合以使它们可序列化 我查看了 BeanLib 但它似乎只进行实体的深层复制 而不允许我为实体类中的集合类型指定实现映射 BeanLib 目前不适用于 Hibernate 3 5
  • 使用异步调用时如何从 javascript 更新元刷新?

    我有一个系统 它使用元刷新来注销页面 该系统会在空闲用户后进行清理 不用担心 服务器也会导致会话超时 我开始通过 ajax 进行一些操作 不是真正的 xml 但这不是重点 我可以运行从异步请求返回的javascript 所以我想知道是否可以
  • JAXB - 列表<可序列化>?

    我使用 xjc 制作了一些课程 public class MyType XmlElementRefs XmlElementRef name MyInnerType type JAXBElement class required false
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没

随机推荐

  • windows上安装tensorflow

    tensorflow0 12版本支持windows 需要python3 5 x 安装python3 5 x 下载 python3 5 2 安装 第一个Install Now是默认安装在c盘的 第二个是自己选择安装路径 我选择第二个 同时将A
  • Unity3D魔方游戏如何完成魔方的旋转

    本游戏是我自学unity后制作的第一个游戏 对于通过何种方法来生成魔方 我就不在多做描述了 因为关于生成的代码网上很多 但是关于如何旋转的却很少 在我在网上查找如何旋转魔方的方法时 找到的都是一些复杂的方法 对于我这样的初学者来说很不友好
  • FindBugs-IDEA插件的使用

    一 前言 FindBugs是一款Java静态代码分析工具 与其他静态分析工具 如Checkstyle和PMD 不同 FindBugs不注重样式或者格式 它专注于寻找真正的缺陷或者潜在的性能问题 它可以帮助java工程师提高代码质量以及排除隐
  • Qt 主要框架

    Qt提供了许多不同的框架和模块 用于开发各种类型的应用程序 以下是一些主要的Qt框架 Qt Core 这是Qt的核心模块 提供了基本的非图形功能 例如字符串处理 文件I O 事件处理 容器类等 它也包含信号和槽机制 是Qt应用程序中常用的基
  • 调试厉器addr2line

    addr2line 将地址转换为文件名和行号的命令行工具 在C C 程序的调试过程中 我们通常会使用调试器 如GDB 来定位崩溃或错误的位置 但有时候 我们可能只能获得程序崩溃时的地址 而没有调试器的支持 这时候 addr2line就可以帮
  • el-table实现分页切换后还能继续保持之前的勾选状态

  • MATLAB的输入与输出

    1 MATLAB的输入语句input函数用于接收用户的输入 a 输入数据 1 2 3 4 gt gt x input please input a number please input a number 22 x 22 b 输入字符串 1
  • 程序员沟通障碍之普遍缺乏同理心

    原创文章 转载请注明 现如今半瓶水程序员比历史上以往任何时候都多 而半瓶水一般都比较自大 这样就容易出现在具体的项目讨论当中 各自都觉得自己绝对正确并争得面红耳赤 亦或在与非技术同事讨论问题时候显得冷冰冰 更或者在与异性相处时候让人觉得不解
  • ArcGIS Pro矢量(shp)裁栅格(tif)

    需求描述 手上有一个矢量面数据 shp格式 有一个栅格数据 tif格式 矢量面就是研究区 栅格就是一个数据集 研究区的面积小于数据集的面积 所以需要用研究区的矢量去裁剪数据集 方法和工具 矢量裁剪栅格的工具有很多 在ArcGIS Pro中
  • 【python】一篇玩转正则表达式

    目录 前言 正则表达式 行定位符 1 2 元字符 常见的元字符 限定符 常用的限定符 字符类 排除字符 选择字符 转义字符 python使用正则表达式 匹配字符串 match search findall sub 替换敏感字符 split
  • (详解及使用)import()函数和import语句

    目录 背景 一 import 1 1 使用场景 二 import from 2 1 详细使用 背景 我们在日常开发中是不是会遇到这个东西import 但是import会有两种形式 下面将详细解释 一 import import函数可以异步动
  • 动态规划 Leetcode 72 Edit Distance(编辑距离)

    题目 给你两个单词 word1 和 word2 请你计算出将 word1 转换成 word2 所使用的最少操作数 你可以对一个单词进行如下三种操作 1 插入一个字符 2 删除一个字符 3 替换一个字符 示例 1 输入 word1 horse
  • PostMan的使用注意事项

    在使用postman的时候 记得把参数的值都给全了 不要少参数 否则会报错 提交的参数写在Params的key value对里就行 还要记得路径要写对
  • 牛顿迭代法求解多元函数的最小值--以二元函数为例

    python 牛顿迭代法求解多元函数的最小值 以二元函数为例 本文转载链接 https blog csdn net qq 45726331 article details 115804812 一元函数到多元函数的牛顿迭代法 python代码
  • 【数据结构】(树总结)二叉树搜索/查找树

    转载来源 https blog csdn net abc 12366 article details 79428739 普通查找树bst 承接之前的 树 本文将目标特别锁定在 查找树 这里整理出我遇到的各种形式的查找树 以后可能会不定期更新
  • JavaScript数据结构——字典

    JavaScript中的字典 字典的特点 键值一一对应 字典和数组对比 字典可以非常方便的通过key来搜索对应的value key可以包含特殊含义 也更容易被人们记住 字典和对象 在其他语言中字典和对象区分比较明显 对象通常是一种在编译期就
  • html src设置二进制流,如何从可中止的AJAX请求返回二进制图像数据并将结果设置为HTML / DOM图像的src?...

    我正在编写一个Web应用程序 它涉及在网页上创建 和删除 大量图像的连续循环 每个图像由服务器动态生成 var img document createElement img img src http mydomain com myImage
  • Maven依赖外部jar包配置

    1 添加依赖路径
  • Abaqus应力结点数据导出与处理

    Abaqus应力数据导出 Abaqus中导出每个应力结点数据 输出数据处理 Abaqus中导出每个应力结点数据 从工具 查询 查询值中打开 如下图所示 接下来点击查询值出现该对话框 在查询值对话框内依次点击选择一个显示组 位置 选择单元结点
  • Typescript结合React实践

    作者 慕晨同学 原文地址 https juejin im post 5d37b5d9f265da1bd605e5e1 写在前面 Typescript是JavaScript的一个超集 主要提供了类型系统和对es6的支持 本人使用ts编写rea