useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用。
父、子组件在使用该hook时步骤如下:
- 父组件使用useRef(或createRef)创建一个ref对象,将这个ref对象赋给子组件的ref属性
- 子组件使用forwardRef包装自己,允许作为函数组件的自己使用ref。然后使用useImperativeHandle钩子函数,在该钩子函数的第二个函数参数中返回一些状态或方法,这个被返回的状态或方法就可以被父组件访问到。
- 父组件使用创建的ref对象的current属性获取子组件暴露出的状态或方法
import React, { useRef, useImperativeHandle } from 'react';
import ReactDOM from 'react-dom';
// 子组件用React.forwardRef包裹
const ChildComponent = React.forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} type="text" />
});
const FatherComponent = props => {
const Ref = useRef();
return (
<div>
<ChildComponent ref={Ref} />
<button onClick={() => Ref.current.focus()}>父组件调用子组件的focus</button>
</div>
)
}
ReactDOM.render(<Father />, root);