React中加入TypeScript的变化

React中使用TypeScript

使用 CRA 创建支持 TS 的项目

React 脚手架工具 create-react-app(简称:CRA)默认支持 TypeScript。
创建支持 TS 的项目命令:npx create-react-app 项目名称 --template typescript。
当看到以下提示时,表示支持 TS 的项目创建成功:
在这里插入图片描述

结构变化

相对于非 TS 项目,目录结构主要由以下三个变化:

  1. 项目根目录中增加了 tsconfig.json 配置文件:指定 TS 的编译选项(比如,编译时是否移除注释)。
  2. React 组件的文件扩展名变为:*.tsx。
  3. src 目录中增加了 react-app-env.d.ts:React 项目默认的类型声明文件。
    在这里插入图片描述

React 项目默认的类型声明文件

react-app-env.d.ts:**React 项目默认的类型声明文件
三斜线指令:指定依赖的其他类型声明文件,types 表示依赖的类型声明文件包的名称。

/// <reference types="react-scripts" />

解释:告诉 TS 帮我加载 react-scripts 这个包提供的类型声明。
react-scripts 的类型声明文件包含了两部分类型:

  1. react、react-dom、node 的类型
  2. 图片、样式等模块的类型,以允许在代码中导入图片、SVG 等文件。
    TS 会自动加载该 .d.ts 文件,以提供类型声明(通过修改 tsconfig.json 中的 include 配置来验证)。

TS 配置文件 tsconfig.json

tsconfig.json 指定:项目文件和项目编译所需的配置项

 {
  //编译选项
  "compilerOptions": {
    //生成代码的语言版本
    "target": "es5",
    //指定要包含在编译中的library
    "lib": [ "dom","dom.iterable","esnext"],
    //允许ts编译器编译js文件
    "allowJs": true,
    //跳过声明文件的类型检查
    "skipLibCheck": true,
    //es模块互操作、屏蔽ESModule和CommonJS之间的差异
    "esModuleInterop": true,
    //允许通过import x from 'y' 即使模块没有显式指定default导出
    "allowSyntheticDefaultImports": true,
    //开启严格模式
    "strict": true,
    //对文件名称强制区分大小写
    "forceConsistentCasingInFileNames": true,
    //为Switch语句启用错误报告
    "noFallthroughCasesInSwitch": true,
    //生成代码的模块化标准
    "module": "esnext",
    //模块解析(查找)策略
    "moduleResolution": "node",
    //允许导入扩展名为.json的模块
    "resolveJsonModule": true,
    //是否将没有import/export 的文件视为旧(全局而非模块化)脚本文件
    "isolatedModules": true,
    //编译时不生成任何文件
    "noEmit": true,
    //指定将jsx编译成什么形式
    "jsx": "react-jsx"
  },
  //指定允许ts处理的目录
  "include": [
    "src"
  ]
  
}

注意:TS 的配置项非常多(100+),以 CRA 项目中的配置为例来学习,其他的配置项用到时查文档即可。

  1. tsconfig.json 文件所在目录为项目根目录(与 package.json 同级)。
  2. tsconfig.json 可以自动生成,命令:tsc --init。

React 中的常用类型

  1. React 项目是通过 @types/react、@types/react-dom 类型声明包,来提供类型的。
  2. 这些包 CRA 已帮我们安装好(react-app-env.d.ts),直接用即可。

函数组件定义类型

函数组件的类型以及组件的属性
   import React from 'react';
  type Props = { name: string; age?: number }
  //第一种写法
  const Hello:React.FC<Props>=({ name, age }) => (<div>你好、我叫{name},今年{age}岁了</div>)

  //第二种写法简化(完全按照函数在 TS 中的写法)
  //const Hello = ({ name, age }:Props) => (<div>你好、我叫{name},今年{age}岁了</div>)
  function App() {
    return (
      <div >
        <Hello name='李寒松' age={18} />
      </div>
    );
  }
  export default App;
  
函数组件属性的默认值(defaultProps)
//指定默认值
Hello.defaultProps={
  age:20
}

//指定默认值简化版
 const Hello = ({ name, age=23 }:Props) => (<div>你好、我叫{name},今年{age}岁了</div>)

  #### 事件绑定和事件对象
    <button onClick={onClick}>点我</button>
    <input onChange={onChange}  />

  //为点击事件指定类型
  const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
    console.log('我是点击事件')

  }
  //为输入框 事件指定类型
  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value)
  }

  技巧:在 JSX 中写事件处理程序(e => {})
  然后,把鼠标放在 e 上,利用 TS 的类型推论来查看事件对象类型。

  //const onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
  

class 组件定义类型

class 组件的类型
  type State={ count:number}
  type Props={ message?:string}

  //无props、无state
  class C1 extends React.Component{}
  //有props、无state
  class C2 extends React.Component<Props>{}
  //无props、有state
  class C3 extends React.Component<{},State>{}
  //有props,state
  class C3 extends React.Component<Props,State>{}
  #### class 组件的属性和属性默认值
class 组件的属性和属性默认值
type PropsLHS={ name:string;age?:number}
class Test extends React.Component<PropsLHS>{
  //提供属性的默认值 
//static  defaultProps:Partial<PropsLHS>={age:24}
  render(){
    //默认值简写
    const {name,age=18}=this.props
    return (
      <div>
        你好、我叫:{name}、我{age}岁了
      </div>
    )
  }
}
<Test name='小天'/>

class 组件的组件状态和事件
import React from 'react';

type State = { count: number }
//<{}, State>传递类型参数
export default class Counter extends React.Component<{}, State> {
  //创建属性的时候提供一个类型
  state: State = {count: 0}
  handleClick = () => this.setState({count:this.state.count+1})
  render() {
    return (
      <div>
        <div>
          计数器:{this.state.count}&nbsp;&nbsp;
          <button onClick={this.handleClick}>加一</button>
        </div>
      </div>
    );
   }
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值