Nav*_*nam 5 typescript reactjs use-ref
该代码是使用 React 功能组件编写的。
单击父级中的按钮后,应触发函数 showAlert。这就是要求。
目前在父组件childRef.current中无法调用showAlert()函数。我收到打字稿错误
Property 'showAlert' does not exist on type 'ForwardRefExoticComponent<RefAttributes<unknown>>'
父功能组件代码
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
import Child from './Child';
export default function App() {
const childRef = useRef<typeof Child>(Child);
return (
<div className="container">
<Child ref={childRef} />
<button
onClick={() => { childRef.current.showAlert() }}
>
Call Function
</button>
</div>
)
}
Run Code Online (Sandbox Code Playgroud)
子功能组件
import React, { forwardRef, useRef, useImperativeHandle } from 'react';
const Child = forwardRef((props, ref) => {
useImperativeHandle(
ref,
() => ({
showAlert() {
alert("Child Function Called")
console.log('hello world')
}
}),
)
return (
<div>Child Component</div>
)
})
export default Child
Run Code Online (Sandbox Code Playgroud)
Lin*_*ste 20
你已经得到了这几乎是正确的,但typeof Child没有给你一个准确的类型,因为Child组件本身的类型不够严格。它被推断为forwardRef<unknown, {}>. 我们需要指定转发引用的类型才能使其正常工作。
我们可以为我们想要的 ref 定义一个接口:
interface CanShowAlert {
showAlert(): void;
}
Run Code Online (Sandbox Code Playgroud)
我们在函数上设置了两个泛型forwardReffor Child。 CanShowAlert是 ref 类型,{}是 props 类型:
const Child = forwardRef<CanShowAlert, {}>((props, ref) => {
Run Code Online (Sandbox Code Playgroud)
我们在 上使用相同的泛型useRef:
const childRef = useRef<CanShowAlert>(null);
Run Code Online (Sandbox Code Playgroud)
您的初始值会出现错误useRef<CanShowAlert>(Child),因为 ref 是针对组件的实例,但您传入的是组件函数本身。相反,我们使用null作为初始值。
ref 的属性current要么是组件实例,要么是,因此我们需要在调用函数之前null确保它不是。为此,我们可以使用可选的链接运算符。nullshowAlert?.
childRef.current?.showAlert()
Run Code Online (Sandbox Code Playgroud)
完整代码:
import React, {forwardRef, useRef, useImperativeHandle} from "react";
interface CanShowAlert {
showAlert(): void;
}
export default function App() {
const childRef = useRef<CanShowAlert>(null);
return (
<div className="container">
<Child ref={childRef} />
<button
onClick={() => { childRef.current?.showAlert() }}
>
Call Function
</button>
</div>
)
}
const Child = forwardRef<CanShowAlert, {}>((props, ref) => {
useImperativeHandle(
ref,
() => ({
showAlert() {
alert("Child Function Called")
console.log('hello world')
}
}),
)
return (
<div>Child Component</div>
)
})
Run Code Online (Sandbox Code Playgroud)