forwardRef 是 React 中的一个高级功能,它允许你将一个 ref 传递给子组件,即使该子组件是通过函数式组件定义的。这在某些情况下很有用,比如当你需要直接访问 DOM 元素或类组件的实例时。
vue则通过this.$refs.XX或this.$children访问子组件的Dom节点对象。
基本用法代码例子
//FancyButton.js
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
//FancyButton 是一个函数式组件
//我们使用 useRef 钩子来创建一个 buttonRef,它将引用内部的 <button> 元素。然后,我们使用 //useImperativeHandle 钩子来定义 ref 的值,使其只暴露一个 focus 方法。
//这样,当外部组件通过 ref 访问 FancyButton 时,它们只能调用 focus 方法,
//而不能直接访问内部的 DOM 元素或组件状态。
const FancyButton = forwardRef((props, ref) => {
const buttonRef = useRef();
//可以使用被称为命令式句柄(imperative handle)
//的自定义对象暴露一个更加受限制的方法集,而非整个 DOM 节点
//**如果某个组件得到了 FancyButton 的 ref,则只会接收到 { focus } 对象**
//**而非整个 DOM 节点。这可以让 DOM 节点暴露的信息限制到最小。**
useImperativeHandle(ref, () => ({
focus: () => {
if (buttonRef.current) {
buttonRef.current.focus();
}
}
}));
return <button ref={buttonRef} {...props}>Click me</button>;
});
父组件:
// FancyButton 是一个函数式组件,我们通过 forwardRef 使其可以接受一个 ref
function App() {
const fancyButtonRef = React.createRef();
//handleClick 点击事件回调方法
const handleClick = () => {
//获取到子组件的Dom节点,并调用focus方法
fancyButtonRef.current.focus();
};
return (
<div>
<FancyButton ref={fancyButtonRef} />
<button onClick={handleClick}>Focus FancyButton</button>
</div>
);
}
export default App;