Typescript的基本介绍

  1. TypeScript 的定位是静态类型语言,在写代码阶段就能检查错误,而非运行阶段

  2. 类型系统是最好的文档,增加了代码的可读性和可维护性。

  3. 有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)等

  4. ts最后被编译成js

创建项目(ts)

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

image

TS + 类组件

  • react中使用最多的就是接口(interface),因为我们要限制组件中的状态,属性等…

类组件的定义方法:

// 定义传参(props)接口
interface propsIn {
name: string,//必须有name属性且为string形式
age?: number,//可以有age属性且必须为number形式
add?: Function,//可以有add属性且必须为函数
}

// 定义状态(state)接口
interface stateIn {
name: string,//必须有name属性且必须为string
}

class HelloClass extends Component<propsIn, stateIn> {
// 创建状态
state = {
name:'lam',
}
render(){
return (
<div>
{/* 展示数据 */}
{this.state.name}
</div>
)
}
}
  • Component<P = {}, S = {}, SS: any>:泛型
  • 第一个参数 P,表示props的类型
  • 第二个参数 S,表示state的类型
  • 第三个参数 SS,表示 SnapShot 的类型

案例展示

  • 这里使用一个todolist案例来展示一下使用ts来编写类组件,要求如下:父组件通过input框输入信息,随后保存到父组件的状态中(list),通过props传参将状态中的list展示到子组件中,同时父组件中设置一个删除函数,用于删除状态中list的某一项,同样传给子组件进行使用
import React, { Component, createRef } from 'react'

/*
使用ts来写类组件,首先要设置接口来限制[属性传参](props)和[状态](state)
随后在组件创建的时候以泛型的形式去限制改类组件的
*/

// [子组件]props的接口(限制props中有list属性,且为字符串形式的数组)
interface propsInterface {
list: string[],//传递过去给子组件展示的list
del: Function,//删除方法(通知父组件删除对应的状态)
};

// [父组件]state的接口(限制state中有两个属性且限制属性类型)
interface stateInterface {
text?: string,//输入框内容(?表示为可选属性)
list:string[],//list内容
}

/* ----------------------- 父组件 ------------------------------ */
export default class App extends Component<any,stateInterface> {//any表示不作类型限制,任意属性,就是js
// 设置状态
state = {
text:'',
list:[]
}
// 创建ref属性(指定为HTMLInputElement)
myref = React.createRef<HTMLInputElement>()

// 创建删除list的方法
Del = (index:number)=>{
console.log('要删除的初始位置',index);
var newList:string[] = [...this.state.list]
newList.splice(index,1)// 删除对应的list
this.setState({
list:newList
})
}

render() {
return (
<div>
<h1>TodoList</h1>
{/* 方法一:使用onChange实现数据的获取和绑定 */}
{/* <input value={this.state.text} onChange={(evt)=>{
console.log('输入框输入的内容:',evt.target.value);

// 调用setState修改状态即可
this.setState({
text:evt.target.value
})
}}/> */}

{/* 方法二:使用ref实现数据的获取和绑定 */}
<input ref={this.myref}/>
<button onClick={()=>{
/*
因为一开始指定的ref中是没有value属性的,也就是所value属性可能为null,
因此我们使用断言语句将该value属性是指定为input标签中的,因为input中必定
有value属性的,不适用断言(as)语句的或会报错
*/
console.log((this.myref.current as HTMLInputElement).value);
this.setState({
// 更新状态
list:[...this.state.list,(this.myref.current as HTMLInputElement).value]
})
}}>add</button>
{/* 将list数据以及删除方法传过去 */}
<Child list={this.state.list} del={this.Del}/>
</div>
)
}
}

/* ------------------------- 子组件 --------------------------- */
class Child extends Component<propsInterface,any> {
render() {
console.log('父组件传过来的数据',this.props);
return (
<div>
<h2>子组件,展示父组件传过来的list</h2>
{
this.props.list.map((item,index)=>{
// 展示list
return <li key={index}>{item}
<button onClick={()=>{
// 调用删除方法
this.props.del(index)
console.log(index);
}}>del</button>
</li>
})
}
</div>
)
}
}

结果展示:

image

TS + 函数式组件

  • 函数式组件与类组件基本一致,只不过是将状态变成hooks而已,下面直接进入案例展示环节,还是使用上一个案例,只不过使用函数式组件在写一遍而已!

案例展示:

import React, { useState, useRef } from 'react'//引入状态和ref的hooks

/* ----------------------- 父组件 ------------------------ */
export default function App() {
const [list,setList] = useState<string[]>([])//设置list
const myRef = useRef<HTMLInputElement>(null)//设置ref并指定对应袁元素

// 创建删除list的方法
const Del:Function = (index:number)=>{
console.log('要删除的初始位置',index);
var newList:string[] = [...list]
newList.splice(index,1)// 删除对应的list
setList([...newList])// 修改状态
}
return (
<div>
<h1>TodoList</h1>
<input ref={myRef}/>
<button onClick={()=>{
console.log('输入:',(myRef.current as HTMLInputElement).value);

// 修改状态(将输入框内容添加进list中)
setList([...list,(myRef.current as HTMLInputElement).value])
}}>add</button>
{/* 将list数据以及删除方法一并传递给子组件 */}
<Child list={list} del={Del}/>
</div>
)
}

// [子组件]设置接口限制(限制props传参)
interface propsIn {
list:string[],//必须有list且必须为字符串数组
del:Function,//必须有del且必须为函数
}

/* ----------------------- 子组件 ------------------------ */
// [限制props传参的方法一]:对props形参进行限制(常规Function,推荐使用)
// function Child(props:propsIn) {
// [限制props传参的方法二]:使用泛型对props进行限制(箭头函数)
const Child:React.FC<propsIn> = (props) => {
console.log(props);
return (
<div>
<h2>子组件,展示父组件传过来的list</h2>
{
/* ----------- 遍历展示数据 ---------- */
props.list.map((item,index)=>{
return <li key={index}>{item}
<button onClick={()=>{
// 调用删除方法
props.del(index)
}}>del</button>
</li>
})
}
</div>
)
}

结果展示:

image