React中使用TS+useImperativeHandle
在React中配合TS是最常见不过的事了,不过最近我在练习useImperativeHandle这个Hooks的时候,发现官网用的JS讲解的这个Hooks,而在TS中则会报这样的错。
Property 'setValue' does not exist on type 'never'.
在React的官方文档关于这个Hooks的用例介绍用的是JS,所以我们也没办法通过查阅官方文档来解决这个问题。
很多同学为了解决这个报错会使用any,将TypeScript用为anyScript,那这样的话使用TypeScript的意义就没有了,无法确保类型安全,也有同学会使用 // @ts-ignore去消除错误,这样的做法我比较不推荐的。
其实消除这个类型报错的方法很简单,我们点进forwardRef中看看类型。
接着,我们点进这个函数类型看看,ref和props的类型传参顺序。
通过这里我们就可以看出,forwardRef函数的类型传参,第一个参数为ref的类型参数,第二个参数为props的类型参数,接下来我们就只需要准备ref的类型即可。
ref的类型根据useImperativeHandle这个Hoos返回的函数指定,例如:
//父组件
'use client'
import { useRef } from "react"
import User from "./user/page"
import { Ref } from "./user/page"
export default function Home() {
const inputRef=useRef<Ref>(null)
function set(){
if(inputRef.current===null){
return;
}
inputRef.current.setValue()
}
return (
<div className=' text-red-600'>
index pages
<User ref={inputRef}/>
<button onClick={set}>点击</button>
</div>
)
}
//子组件
'use client'
import React, { useImperativeHandle,forwardRef,useRef } from 'react'
type Props={
}
export interface Ref {
setValue:()=>void,
}
const User=forwardRef<Ref,Props>(function User(props:Props,ref) {
const inputRef=useRef<HTMLInputElement>(null)
useImperativeHandle(ref,()=>{
return{
setValue(){
if(inputRef.current===null){
return
}
inputRef.current.value="1in"
}
}
},[])
return (
<div>
user
<input type="text" ref={inputRef} />
</div>
)
})
export default User
在上述代码中,因为我的返回值只有setValue这个函数,所以我们ref的类型只需要声明setValue这个函数的类型即可。
注:因为我在Next.js中编写的代码,所以会有最开始的"use client",如果你在React中编写,最开始的"use client"可以忽略