Typescript结合React实践

原创 慕晨同学 前端技术优选 今天

作者:慕晨同学

原文地址: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率降低了,查文档也更加方便,一看类型声明文件就明白了各个字段的含义。

(0)

相关推荐

  • 使用create-react-app搭建TypeScript React Ant Design开发环境

    要创建一个支持TypeScript的Create React App项目,可以运行: npx create-react-app my-app --template typescript# oryarn ...

  • 前端UI组件库搭建和设计

    为什么我们需要一个UI组件库 提高团队的开发效率 提高系统的复用性,可维护性 统一页面基础元素的交互方式 统一页面的风格,让输出的产品更专业 满足一些定制的需求 一个优秀的UI组件库要具备哪些要素 在 ...

  • Vite React 组件开发实践

    简介:毫不夸张的说,Vite 给前端带来的绝对是一次革命性的变化.或者也可以说是 Vite 背后整合的 esbuild . Browser es modules.HMR.Pre-Bundling 等这 ...

  • 徐怀书的经方实践

    徐怀书的经方实践

  • 组织活力建设:PRE 活力模型的构建与应用实践

    方向只能大致正确,组织要确保活力,这远比很多企业家功成名就了总结出来的战略思想靠谱的多. T&D 在多年第四方深度诊断与经营质量变革项目中的经验提炼总结的组织活力模型-PRE 活力模型给更多的 ...

  • 微服务实践之分布式定时任务

    承接上篇:上篇文章讲到改造 go-zero 生成的 app module 中的 gateway & RPC .本篇讲讲如何接入 异步任务 以及 log的使用. Delay Job 日常任务开放 ...

  • 华为高管揭秘:华为公司业务变革与IT治理实践

    2015年,华为预期实现销售收入3900亿人民币(约合600.6亿美元)左右,利润.现金流稳定增长,成为其聚焦管道战略以来见效显著的一年. 华为轮值CEO郭平在新年致辞中表示:新一年中,华为将开始5- ...

  • 对茯苓四逆汤的思考与实践

    作者/周威 茯苓四逆汤是<伤寒论>中的沧海遗珠,医家对此方少有关注.笔者在临证时发现适用此方的场合并不少见.故不揣简陋,将自己对茯苓四逆汤的思考与实践,简述如下,供同仁参考. 一.文献考察 ...

  • 7种人力资源最佳实践

    什么是人力资源最佳实践? 最佳实践是一套通用的人力资源管理流程和行动.在人力资源管理研究中,有两种关于如何管理人员的思想流派:第一个是最合适的,第二个是最佳实践. 最合适的观点指出,为了增加价值,人力 ...

  • 培训的定义、作用和最佳实践

    一.什么是人力资源开发? 人力资源开发一词最早是在1969年提出的,指的是劳动力的培训,教育和发展.它旨在弥合学校教育和工作场所要求之间的差距. 在早期,HRD会进行严格的动手培训,重点是掌握硬技能. ...