首先,我们需要定义一个接口来描述我们希望暴露给父组件的方法。然后,在 useImperativeHandle
中实现这些方法,并确保它们符合这个接口。
TypeScript 示例代码
import React, { useRef, useImperativeHandle, forwardRef, MutableRefObject } from 'react';
// 定义一个接口来描述我们希望暴露给父组件的方法
interface ChildComponentHandles {
focus: () => void;
}
// 子组件接收 ref 并使用 useImperativeHandle 来自定义暴露的方法
const ChildComponent = forwardRef<ChildComponentHandles, {}>((props, ref) => {
const inputRef = useRef<HTMLInputElement>(null);
// 使用 useImperativeHandle 自定义 ref 的 current 属性
useImperativeHandle(ref, () => ({
focus() {
if (inputRef.current) {
inputRef.current.focus();
}
},
// 可以添加更多的方法
}));
return <input ref={inputRef} />;
});
// 父组件通过 ref 调用子组件中定义的方法
const ParentComponent: React.FC = () => {
const childRef = useRef<ChildComponentHandles>(null);
const handleClick = () => {
// 现在可以通过 childRef 调用 ChildComponent 中定义的 focus 方法
if (childRef.current) {
childRef.current.focus();
}
};
return (
<>
{/* 将 ref 传递给子组件 */}
<ChildComponent ref={childRef} />
<button onClick={handleClick}>Focus Input</button>
</>
);
};
export default ParentComponent;
关键点解释
-
接口定义:
- 我们定义了一个名为
ChildComponentHandles
的接口,它规定了focus
方法的签名。
- 我们定义了一个名为
-
forwardRef
和泛型参数:- 在
forwardRef
中,我们使用了两个泛型参数:第一个是ChildComponentHandles
,表示我们将要暴露给父组件的方法集合;第二个是{}
,代表组件的 props 类型(在这个例子中没有使用任何额外的 props)。
- 在
-
useImperativeHandle
:- 我们使用
useImperativeHandle
来指定当父组件访问childRef.current
时返回的对象应该包含哪些方法。这里我们实现了focus
方法,该方法调用了内部inputRef
的focus
方法。
- 我们使用
-
useRef
和类型注解:- 在
ParentComponent
中,我们使用useRef<ChildComponentHandles>(null)
来创建一个带有特定类型的ref
,这样 TypeScript 就知道childRef.current
应该有哪些属性和方法。
- 在
-
安全检查:
- 在调用
focus
方法之前,我们进行了空值检查 (if (childRef.current)
) 以避免可能的运行时错误。
- 在调用
这段代码展示了如何在 TypeScript 中正确地使用 forwardRef
和 useImperativeHandle
来控制从子组件到父组件的交互方式,同时保持了良好的类型安全性和可读性。
前端工程师、程序员
标签:
react18
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~