可以使用extends关键字来对泛型参数进行限制
interface IWithLengh {
length: number;
function echoWithLength<T extends IWithLengh>(arg: T): T {
console.log(arg.length);
return arg;
const str = echoWithLength('abc');
const obj = echoWithLength({ length: 1 });
const arr = echoWithLength([1, 2])
类也可以使用泛型来约束
class Queue<T> {
private data: T[] = [];
push(item: T): void {
this.data.push(item);
pop(): T {
return this.data.pop();
const queue = new Queue<number>();
queue.push(1);
console.log(queue.pop().toFixed(2));
const queue2 = new Queue<string>()
接口也可以使用泛型来约束
interface KeyPair<T, U> {
key: T;
value: U;
}
使用泛型来约束函数
interface IPlus<T> {
(a: T, b: T): T;
function plus(a: number, b: number): number {
return a + b;
const a: IPlus<number> = plus
该hook默认会在第一次渲染完成和每次界面更新时执行,相当于class组件中的componentDidMount和componentDidUpdate
useEffect(() => {
document.title = `点击了${like}次`
})
使用useEffect的返回值清除副作用
const LikeButton: React.FC = () => {
const [position, setPosition] = useState({ x: 0, y: 0 })
useEffect(() => {
const updatePostion = (e: MouseEvent) => {
setPosition({
x: e.clientX,
y: e.clientY
document.addEventListener('click', updatePostion)
return () => {
document.removeEventListener('click', updatePostion)
return <p>X: {position.x}, Y: {[position.y]}</p>
}
控制useEffect执行时机,这里需要使用到useEffect的第二个参数。第二个参数是一个数组,可以填入依赖项,当这些依赖项发生变化时,才会去执行useEffect。当第二个参数为空数组,显然这种情况是没有依赖可以变化的,因此这种情况的useEffect仅仅会在组件加载和卸载时执行一次。
useEffect(() => {
document.title = `点击了${like}次`
}, [like])
自定义hook需要以use开头
const useMousePosition = () => {
const [position, setPosition] = useState({ x: 0, y: 0 })
useEffect(() => {
const updatePostion = (e: MouseEvent) => {
setPosition({
x: e.clientX,
y: e.clientY
document.addEventListener('click', updatePostion)
return () => {
document.removeEventListener('click', updatePostion)
}, [])
return position
}
使用一个自定义hook
const position = useMousePosition()
使用自定义hooks封装一个请求公共hooks
import { useState, useEffect } from 'react'
import axios from 'axios'
const useURLLoader = (url: string, deps: any[] = []) => {
const [data, setData] = useState<any>(null)
const [loading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
axios.get(url).then(result => {
setData(result.data)
setLoading(false)
}, deps)
return data
export default useURLLoader