• React项目中应用TypeScript


    一、前言

    单独的使用typescript 并不会导致学习成本很高,但是绝大部分前端开发者的项目都是依赖于框架的

    例如和vuereact 这些框架结合使用的时候,会有一定的门槛

    使用 TypeScript 编写 react 代码,除了需要 typescript 这个库之外,还需要安装@types/react@types/react-dom

    npm i @types/react -s

    npm i @types/react-dom -s

    至于上述使用@types的库的原因在于,目前非常多的javascript库并没有提供自己关于 TypeScript 的声明文件

    所以,ts并不知道这些库的类型以及对应导出的内容,这里@types实际就是社区中的DefinitelyTyped库,定义了目前市面上绝大多数的JavaScript库的声明

    所以下载相关的javascript对应的@types声明时,就能够使用使用该库对应的类型定义

    二、使用方式

    在编写react项目的时候,最常见的使用的组件就是:

    • 无状态组件
    • 有状态组件
    • 受控组件

    无状态组件

    主要作用是用于展示UI,如果使用js声明,则如下所示:

    import * as React from 'react'

    export const Logo = props => {
        const { logo, className, alt } = props

        return (
            <img src={logo} className={className} alt={alt} />
        )
    }

    但这时候ts会出现报错提示,原因在于没有定义porps类型,这时候就可以使用interface接口去定义porps即可,如下:

    import * as React from 'react'

    interface IProps {
        logo?: string
        className?: string
        alt?: string
    }

    export const Logo = (props: IProps) => {
        const { logo, className, alt } = props

        return (
            <img src={logo} className={className} alt={alt} />
        )
    }

    但是我们都知道props里面存在children属性,我们不可能每个porps接口里面定义多一个children,如下:

    interface IProps {
        logo?: string
        className?: string
        alt?: string
        children?: ReactNode
    }

    更加规范的写法是使用React里面定义好的FC属性,里面已经定义好children类型,如下:

    export const Logo: React.FC<IProps> = props => {
        const { logo, className, alt } = props

        return (
            <img src={logo} className={className} alt={alt} />
        )
    }

    • React.FC显式地定义了返回类型,其他方式是隐式推导的

    • React.FC对静态属性:displayName、propTypes、defaultProps提供了类型检查和自动补全

    • React.FC为children提供了隐式的类型(ReactElement | null)

    有状态组件

    可以是一个类组件且存在propsstate属性

    如果使用typescript声明则如下所示:


    import * as React from 'react'

    interface IProps {
      color: string,
      size?: string,
    }
    interface IState {
      count: number,
    }
    class App extends React.Component<IProps, IState> {
      public state = {
        count: 1,
      }
      public render () {
        return (
          <div>Hello world</div>
        )
      }
    }

    上述通过泛型对propsstate进行类型定义,然后在使用的时候就可以在编译器中获取更好的智能提示

    关于Component泛型类的定义,可以参考下 React 的类型定义文件 node_modules/@types/react/index.d.ts,如下所示:

    class Component<P, S> {

        readonly props: Readonly<{ children?: ReactNode }> & Readonly<P>;

        state: Readonly<S>;

    }

    从上述可以看到,state属性也定义了可读类型,目的是为了防止直接调用this.state更新状态

    受控组件

    受控组件的特性在于元素的内容通过组件的状态state进行控制

    由于组件内部的事件是合成事件,不等同于原生事件,

    例如一个input组件修改内部的状态,常见的定义的时候如下所示:

    private updateValue(e: React.ChangeEvent<HTMLInputElement>) {
        this.setState({ itemText: e.target.value })
    }

    常用Event 事件对象类型:

    • ClipboardEvent<T = Element> 剪贴板事件对象
    • DragEvent<T = Element> 拖拽事件对象
    • ChangeEvent<T = Element>  Change 事件对象
    • KeyboardEvent<T = Element> 键盘事件对象
    • MouseEvent<T = Element> 鼠标事件对象
    • TouchEvent<T = Element>  触摸事件对象
    • WheelEvent<T = Element> 滚轮事件对象
    • AnimationEvent<T = Element> 动画事件对象
    • TransitionEvent<T = Element> 过渡事件对象

    T接收一个DOM 元素类型

    三、总结

    上述只是简单的在react项目使用typescript,但在编写react项目的时候,还存在hooks、默认参数、以及store等等......

    typescript在框架中使用的学习成本相对会更高,需要不断编写才能熟练

    本文来自博客园,作者:喆星高照,转载请注明原文链接:https://www.cnblogs.com/houxianzhou/p/15293639.html

  • 相关阅读:
    服务器与本地时间的倒计时
    没有花括号(大括号)的for循环也能正确执行
    js瀑布流效果
    AQS详解(AbstractQueuedSynchronizer)
    SimpleDateFormat的线程安全问题与解决方案
    jvm不打印异常栈
    Java中的序列化Serialable高级详解
    java梳理-序列化与反序列化
    AQS详解
    对ConditionQueue和锁的理解
  • 原文地址:https://www.cnblogs.com/houxianzhou/p/15293639.html
Copyright © 2020-2023  润新知