React中使用TS


在React中使用typescript

React脚手架 + typescript

npx create-react-app my-app --template typescript

如果是对当前React脚手架项目添加typescript支持

npm install --save typescript @types/node @types/react @types/react-dom @types/jest

但是有个问题就是:将 TypeScript 添加到现有项目不会添加 tsconfig

https://github.com/facebook/create-react-app/issues/10951

作为一种较为无语的解决方法:

作为一种解决方法,我通过运行创建了一个新的 react 应用程序:
npx create-react-app ts-example --template typescript
然后将生成的 tsconfig.json 的内容复制粘贴到我现有的应用程序中。

对于类式组件

在构建React组件类的时候,还有这一种接口的写法 React.Component<props接口的名称, state接口的名称>,用来说明派生的 Component 使用的 Props 和 State 的类型

React.Component<Props, State>

ref对象,我们也需要手动声明它的类型

myRef = React.createRef<ref的元素类型>()

比如以下例子

import React, { Component, createRef } from 'react';
interface IState {
  name: string
}
// 泛型第一个约定props属性、第二个约定状态
class App extends Component<any, IState> {
  state = {
    name: "allen"
  }
  myRef = createRef<HTMLInputElement>()
  render() {
    return (
      <div>
        <input type="text" ref={ this.myRef}/>
        <button onClick={
          () => {
            console.log((this.myRef.current as HTMLInputElement).value);
         }
        }></button>
        <Child name={this.state.name}></Child>
      </div>
    );
  }
}
interface IProps {
  name: string
}
class Child extends Component<IProps, IState> {
}
export default App;

对于函数式组件

函数式组件十分轻松,不用做什么处理,作为状态state已经被隐式推导了

而其他的规范也十分轻松

import React, {useState, useRef} from 'react'
//非要自己显式也不是不行:  const [name, setName] = useState<string>("allen")
interface IProps {
  name: string
}
export default function App(props:IProps) {
  const [name, setName] = useState("allen")
  const inputRef = useRef<HTMLInputElement>(null)
  return (
    <div>
      <div>{name}</div>
      <input type="text" ref={inputRef}/>
      <button onClick={
        () => {
          setName("Mikasa")
          console.log((inputRef.current as HTMLInputElement).value);
        }
    }></button>
    </div>
  )
}

react路由+TS

对于react-router-dom,无法直接使用,需要声明文件(declare)(或者你自己写声明文件,手动狗头)

npm i --save-dev @types/react-router-dom

注意事项:作为路由组件,应该带有三个属性:history、location、match


首先引入 RouteComponentProps props的声明,得到路由组件的类型推断

其次可以在该声明中传入泛型,这个泛型是指定路由参数(params)类型的泛型

import React, { useState, useRef } from 'react'
import {RouteComponentProps} from 'react-router-dom';
interface IParams {
  name: string
}
export default function App(props:RouteComponentProps<IParams>) {

  return (
    <div>
      {props.match.params.name}
    </div>
  )
}

redux+TS

redux已经有声明文件了,这里不用下载

三个文件

  • 新建 store.js
  • 新建一个处理xxx组件的 xxx-reducer.js
  • 可选,新建一个处理xx组建的xxx-action.js

store几乎照常写就行了,而reducer和action传参的时候小小修改一下

interface IAction {
  type: string;
  payload?: any;
}
interface IPreState {
  isShow: boolean
}
export default function countReducer(preState: IPreState = {
  isShow: true
}, action: IAction) {
  const { type, payload } = action;
  let newState = preState;
  //...
  return newState;
}

小坑

alias

关于TS在create react app应用的小坑

webpack配置

module.exports = {
  //...
  resolve: {
    alias: {
      '@': path.join(__dirname, '../src')
    }
  }
};

但是在项目中使用alias转换的全局路径,ts不买账

为了解决这个问题,需要借助tsconfig,尽管webpack已经配置好了alias, 可是ts并不认账。

tsconfig.json配置如下

需要在compilerOptions 增加2个字段, baseUrl 指定当前工程的路径, paths 用于对别名的映射。

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
    // ...
  }
}

在此就能解决上述问题了,如果不行可能需要重启vscode。


文章作者: Hello
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Hello !
 上一篇
BOM BOM
1.BOM概述BOM是浏览器对象模型,他提供独立于内容而与浏览器窗口进行交互的对象,其核心对象是window BOM缺乏标准,Javascript语法的标准化组织是ECMA,DOM标准化组织是W3C,BOM最初是Netscape浏览器标准的
2022-03-05
下一篇 
MongoDB MongoDB
1.MongoDB概述MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。 mongoDB不需要学习sql语句 NoSQL,指的是非关系型的数据库。NoSQL有时也
2022-02-26
  目录