关于React Hook使用TypeScript遇到的问题记录

最近使用 React + Hook + TS 写了一个练手的demo,练习了 React + Hook 的 TypeScript 写法。本文主要记录自己在写demo过程中,遇到关于 TypeScript 写法上的坑。

demo地址:「ts-todo」

1. 创建 TS 项目

使用create-react-app创建React项目,应该没有什么坑,记得在创建React项目的时候,添加typescript配置即可:

npx create-react-app app-name --template typescript

2. 在 React Hook 中 TS 写法

将所有.js文件全部更名为.ts后缀,所有.jsx文件更名为.tsx,若还使用 JavaScript 的写法的话,项目还是能运行的,但配置了 TypeScript 还写 JavaScript 就达不到练手的目的了!

在写demo的过程中,遇到了如下几个坑,经过查找后得到了解决,特此记录。

1. 函数组件

既然要用 React Hook,就需要写函数组件,我们需要告诉 TypeScript,这个函数是个 React 组件,在 JavaScript 中,通常这样定义一个函数组件:

const App = () => {
    return <>App</>;
};

配置了 TypeScript,就需要加上函数类型。React 提供了React.FunctionComponent的类型,意思是函数组件,我们可以直接简写为React.FC,如下代码所示:

const App: React.FC = () => {
    return <>App</>;
};

2. 类型声明举例

一些简单的类型声明,比如numberstringboolean类型的,只需在声明的变量后面加上:[类型]即可。

比如,定义一个number类型的ageboolean类型的isDone

let age: number = 37;
let isDone: boolean = false;

在写demo中,我使用到一个对象数组,如下结构:

[
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
]

那么一般的array类型已经满足不了了,这时就需要再定义一个interface

interface TaskObj {
    id: string;
    content: string;
    isDone: boolean;
}

注意:接口名通常是大写字母开头。

这个interface表示,定义的对象需要同时满足以下条件:

  • id属性,且类型为string
  • content属性,且类型为string
  • isDone属性,且类型为boolean

TypeScript并不会检查属性的顺序,只需相应的属性存在,并且类型也满足即可。

这时候定义单个对象,就可以使用刚刚定义的interface了:

const obj: TaskObj = { id: 'xxxx', content: 'xxxxxxx', isDone: false };

但如果需要定义上述的对象数组,需要这样写:

const allTasks: TaskObj[] = [
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
];

TaskObj[]表示该类型是一个数组,数组里的元素需要满足TaskObj接口。

3. useState

对于存储string类型的state,在useState右边加上<string>即可:

const [input, setInput] = useState<string>('');

实际上,useState<string>('')已经给了初始值'',那么 TypeScript 会自动类型判断,即使不写<string>也可以。

如果要存储的数据结构如下:

[
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
    { id: 'xxxx', content: 'xxxxxxx', isDone: false },
]

那么还是需要上文提到的interface

interface TaskObj {
    id: string;
    content: string;
    isDone: boolean;
}

const [task, setTask] = useState<TaskObj[]>([]);

4. 父组件给子组件传参

在 JavaScript 中,父组件给子组件传递参数,直接子组件上写,子组件通过props接收即可:

<Doing doing={doing} setTask={setTask} />

但是 TypeScript 若直接这么写会报错,原因是子组件并没有满足传递参数的接口,需要自己定义接口。

如上代码,在子组件Doing外,需要定一个满足传递参数的接口:

interface DoingProps {
    doing: TaskObj[];
    setTask: Function;
}

const Doing: React.FC<DoingProps> = ({ doing, setTask }) => {
	...
}

如上代码,定义了一个DoingProps接口,并且在子组件的React.FC后添加<DoingProps>,表明该组件接收的参数需要满足如下条件:

  • doing属性,且类型为数组,数组的元素满足TaskObj接口。
  • setTask属性,且类型是一个函数。

这样,父组件给子组件传参的过程就用 TypeScript 实现了。

5. 类型断言

在写demo中,需要拿到一个输入框的DOM节点,写了如下代码:

const inputNode: HTMLInputElement = document.getElementById(`${id}`)

TypeScript 却提示有如下错误:

这时候只需加上类型断言即可,明确告诉编译器变量的类型:

const inputNode: HTMLInputElement = document.getElementById(`${id}`) as HTMLInputElement;

6. 键盘事件

需要判断按下的按键,这时候需要键盘事件对象,用 TypeScript 来写,需要先将键盘事件KeyboardEvent引入:

import { KeyboardEvent } from 'react';

传递事件对象参数时,需要指明为键盘事件:

<input 
    type="text" 
    defaultValue="{obj.content}" 
    onKeyDown={(e: KeyboardEvent) => updateTask(e, obj.id, obj.content)}
/>

updateTask函数定义如下:

const updateTask = (e: KeyboardEvent, id: string, oldContent: string) => {
	...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
React HookReact 16.8版本引入的一种新的特性,它可以让你在无需编写类组件的情况下使用状态和其他React特性。TypeScript是一种静态类型检查的JavaScript超集,可以帮助我们在开发过程中发现并修复潜在的误。 要深入学习React HookTypeScript技术栈,你可以按照以下步骤进行: 1. 学习React基础知识:在学习React Hook之前,确保你对React的基础知识有一定的了解。理解React组件、生命周期、状态管理等概念是很重要的。 2. 学习TypeScript基础知识:如果你还不熟悉TypeScript,可以先学习一些基础知识,比如类型注解、接口、泛型等。掌握这些概念可以帮助你更好地使用TypeScript进行开发。 3. 学习React Hook:阅读React官方文档中关于React Hook的内容,并尝试编写一些简单的Hook。掌握useState、useEffect、useContext等常用的Hook函数,并理解它们的使用方法和原理。 4. 使用TypeScript编写React Hook:在掌握了React Hook的基本知识后,你可以开始使用TypeScript编写React Hook使用TypeScript可以为你的代码提供类型检查和智能提示,减少潜在的误。 5. 实践项目:选择一个小型的项目或者练习,使用React HookTypeScript进行开发。通过实践项目可以帮助你更好地理解和掌握这两个技术栈。 6. 深入学习进阶内容:一旦你对React HookTypeScript有了基本的了解,你可以进一步学习一些进阶内容,比如自定义Hook使用第三方库、使用Context API等。 记住,深入学习任何技术栈都需要时间和实践。通过不断地阅读文档、编写代码和解决问题,你会逐渐掌握React HookTypeScript技术栈。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火星飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值