React中常用的类型姿势

431 阅读2分钟

建议安装 @types/react 以及 ## @types/react-dom为devdependency

React内置类型

节点类型

如果你有一个组件接受另外一个组件作为chilren,那你应该如何给这个children声明类型呢?

React里有众多节点类型: JSX.Element,React.ReactChildren,React.ReactChild[],React.ReactNode

答案: 使用ReactNode

JSX.Element 和 React.ReactNode

JSX.Element是React.createElement所返回的数据类型并且总是会是一个对象,而React.ReactNode则涵盖了一个组件所有可能的返回值。同理ReactChild

CSS类型

React.CSSProperties 涵盖所有style类型

事件类型

表单事件 React.FormEventHandle

一个inputdom的 onChange回调可以这么写:
React.FormEventHandler<HTMLInputElement>

Contextual Type

也可以借助ts强大的 Contextual Type:

image.png

观察一下上面两段函数,区别就在于第二个button绑定的回调被当成一个独立函数拆了出来,结果就报了隐式any的类型错误,原因就是ts的 Contextual Type,第一个button所绑定的函数可以获得onClick所在“context”的类型推断!

image.png

常用dom事件类型

以下均可以使用 React[eventType] 方式获取。

  • ChangeEvent 当 元素值value发生法改变时触发的事件类型
  • ClipboardEvent 剪切板事件
  • DragEvent 拖拽
  • PointerEvent 一般触摸屏设备上多点触控事件
  • WheelEvent 滚轮事件
  • SyntheticEvent 合成事件 这个事件类型将涵盖所有react的事件类型因此当你不确定时可以使用这个类型

dom ref

ref非常灵活(既可以存放dom对象也可以存档mutable object)当我们在用ts的情况下使用useRef或者createRef时,往往会遇到各种类型问题。

存放dom时的典型例子

页面上有一个input在页面渲染完成后自动获得焦点。

import React,{ useEffect} from 'react'
function App() {
  const inputEl = React.useRef(null)
  useEffect(()=>{
    inputEl.current.focus()
  },[])
  return (
    <div className="App">
      <input ref={inputEl}/>
    </div>
  )
}

export default App

这段代码在ts下会有两个类型问题:

1.current 对象可能会为null

image.png

解决方法:

// !非空断言
const inputEl = React.useRef(null!)
// ? optional chain
useEffect(()=>{
    inputEl.current?.focus()
},[])

但是仅仅这样还不够因为此时useRef并不知道自己接受到的是什么,它会默认把它当成never来处理

image.png

会提示:

image.png

此时需要依靠泛型来收束我们想要的类型:

// 指定 HTMLInputElement 类型
const inputEl = React.useRef<HTMLInputElement>(null!)

dom类型那么多,我找不到具体名称是哪个怎么办?

写一个错误的html类型,比如一律写成HTMLDivElement 然后编辑器会给你正确的类型提示:

image.png

如此一来就能充分享受类型红利。