环境搭建

我们当然可以先用脚手架搭建React项目,然后手动配置成支持TypeScript的环境,虽然比较麻烦,但可以让你更清楚整个过程。这里比较麻烦,就不演示了,直接用命令配置好。

npx create-react-app appname --typescript

可以安装一些自己需要的库及其声明文件,例如react-router-dom、axios、ant Design等。如果要安装ant design,还需要在开发环境库中安装一些依赖库,以帮助实现按需加载。

使用

有类型约束的函数组件

import React from "react";
import { Button } from "antd"; interface Greeting {
name: string;
firstName?: string;
lastName?: string;
} // 没有使用React.FC
const HelloOld = (props: Greeting) => <Button>你好{props.name}</Button>; // 使用React.FC泛型类型
const Hello: React.FC<Greeting> = (props) => {
return (
<Button>Hello {props.name}</Button>
)
}; export { Hello, HelloOld };

定义函数组件时,使用React.FC与不使用没有太多区别,没有为我们带来明显的好处,建议使用常规定义方式。

有类型约束的类组件

import React,{Fragment} from "react";
import { Button } from "antd"; interface Greeting {
name: string;
firstName?: string;
lastName?: string;
}
interface State {
count: number
} // 泛型类型,第一个传入参数约束属性props,第二个约束状态state(内部数据)
class HelloClass extends React.Component<Greeting, State> {
state: State = {
count: 0
};
static defaultProps = { // 属性默认值
firstName: "",
lastName: "",
}; render() {
return (
<Fragment>
<p>点击了{this.state.count}次</p>
<Button onClick={()=>{this.setState({count: this.state.count+1})}}>Hello{this.props.name}Class</Button>
</Fragment>
);
}
} export default HelloClass;

有类型约束的高阶组件

import React from "react";
import HelloClass from "./HelloClass"; interface Loading {
loading: boolean;
} function HelloHoc<P>(params?: any) {
return function<P>(WrappedComponent: React.ComponentType<P>) { // P表示被包装组件的属性的类型
return class NewComponent extends React.Component<P & Loading>{ // 这里使用交叉类型,为新组件增加一些属性,接口Loading定义了新增的属性声明
render(){
return this.props.loading ? <div>Loading</div> : <WrappedComponent {...this.props as P}/> }
}
}
} export default HelloHoc()(HelloClass);

高阶组件在ts中使用会有比较多的类型问题,解决这些问题通常不会很顺利,而且会存在一些已知的bug,这不是高阶组件本身的问题,而是React声明文件还没有很好地兼容高阶组件的类型检查,更好的方式是使用Hooks

有类型约束的Hooks

import React, { useState, useEffect } from "react";
import { Button } from "antd"; interface Greeting {
name: string;
firstName?: string;
lastName?: string;
} const HelloHooks = (props: Greeting) => {
const [ count, setCount ] = useState(0); // 设了初值,所以不用定义类型
const [ text, setText ] = useState<string | null>(null); useEffect(()=>{
count > 5 && setText("休息一下");
},[count]); // 第二个参数的作用是,只有当count改变的时候,函数内的逻辑才会执行。 return (
<>
<p>你点击了Hooks {count} 次 {text}</p>
<Button onClick={()=>{setCount(count+1)}}>{props.name}</Button>
</>
);
}; export default HelloHooks;

事件绑定

class HelloClass extends React.Component<Greeting, State> {
state: State = {
count: 0
}; clickHandle = (e: React.MouseEvent) => { // 事件对象e的类型使用内置的合成事件。在回调函数中,e的属性都会无效
e.persist(); // 将该事件从池中删除合成事件,可以正常使用
console.log(e);
// this.setState({count: this.state.count+1})
}; inputHandle = (e: React.FormEvent<HTMLInputElement>) => {
// e.persist();
console.log(e.currentTarget.value); // 此时编译器报错,认为没有value属性,需要指定<HTMLInputElement>泛型类型
// console.log(e.target.value); // 仍然不行
}; render() {
return (
<Fragment>
<p>点击了{this.state.count}次</p>
<Button onClick={this.clickHandle}>Hello{this.props.name}Class</Button>
<input onChange={this.inputHandle}/>
</Fragment>
);
}
}

最新文章

  1. es6 中增强的对象字面量
  2. SQLSERVER2008R2数据库的整体导出及单个表的导出步骤
  3. Lua Coroutine详解
  4. Atitit.会员卡(包括银行卡)api的设计
  5. 普通View的measure流程
  6. JSON数据解析(GSON方式) (转)
  7. 提取SD卡中的图片
  8. iOS开发:iOS的整体架构以及API介绍
  9. Android Bundle传递简单数据、对象数据
  10. HTML中标签和元素的区别
  11. J2SE习题(2)
  12. shiro(四)项目开发中的配置、
  13. [Swift]LeetCode216. 组合总和 III | Combination Sum III
  14. windows和linux换行规则的区别
  15. spring aop做什么介绍
  16. react-router-dom v^4路由、带参路由的配置
  17. Linux——awk命令解析
  18. TZOJ 5291 游戏之合成(快速幂快速乘)
  19. AngularJS中实现显示或隐藏动画效果的3种方式
  20. Java| 编译和反编译

热门文章

  1. golang 结合实例更好的理解参数传递和指针
  2. android ——Intent
  3. Linux文件及目录管理
  4. Go开发中的十大常见陷阱[译]
  5. 详解python函数的参数
  6. Java中访问修饰符public、private、protecte、default
  7. 二阶段js 入门知识点 自我总结复习
  8. 七缸发动机预热,docker swarm + .net core 高速飙车成功
  9. 深度学习环境搭建部署(DeepLearning 神经网络)
  10. 一看就懂-Docker容器化