函数式组件不能直接应用 ref。
class ClassComp extends Component {
render() {
return '';
}
}
function FuncComp(props) {
return '';
}
function App() {
let refClass = useRef();
let refFunc = useRef();
return (
<div>
<ClassComp ref={refClass} />
<FuncComp ref={refFunc} />
<button onClick={() => console.log(refClass, refFunc)}>Log</button>
</div>
);
}
对于类组件,ref 实际上指向的是类组件的实例。函数式组件没有实例,因此只能得到 undefined,同时 React 会给出警告。
为了解决这个问题,需要引入 forwardRef 函数。forwardRef 函数能够让函数式组件接受 ref 属性,然后转发给其他可以处理 ref 的组件。
例如将 ref 转发给 DOM 节点,这样就不会出现 undefined 了。
// ...
function _FuncComp(props, ref) {
return <div ref={ref}>123</div>;
}
const FuncComp = forwardRef(_FuncComp);
// ...
有时候并不需要保留 DOM 节点,而是想暴露一些属性或方法对外使用。此时可以使用 useImperativeHandle。
function _FuncComp(props, ref) {
useImperativeHandle(ref, () => {
return {a: 1, foo: () => console.log('foo') };
}, []); // 第三个参数为依赖,类似 useEffect
return <div ref={ref}>123</div>;
}
const FuncComp = forwardRef(_FuncComp);