useImperativeHandle不容易理解,笔者循序渐进讲一讲自己的理解。
回顾一下ref和forwardRef结合使用:
- 通过forwardRef可以将ref转发到子组件;
- 子组件拿到父组件中创建的ref,绑定到自己的某一个元素中。
import React, { useRef, forwardRef } from 'react'
const HYInput = forwardRef((props, ref) => {
return <input ref={ref} type="text" />
})
export default function ForwardRefDemo() {
const inputRef = useRef();
return (
<div>
<HYInput ref={inputRef} />
<button onClick={e => inputRef.current.focus()}>聚焦</button>
</div>
)
}
- 现在通过ref和forwardRef,可以在父组件中随意改变元素。
- 但是我们可能只希望父组件只能对子组件进行有限操作,也就是限制父组件的自由度。
现在看看useImperativeHandle hook怎么使用。
useImperativeHandle最主要接收两个参数:
- ref:;
-
回调函数:要求有一个返回值,返回值一般为对象;
image.png
-
也就是将返回的对象绑定到ref中current里面。
image.png - 所以之后的current,就是我们返回的那个对象。
-
在返回的该对象中,对其暴露的方法进行操作;一般来说,只要用到forwardRef,那么最好搭配该hook一起使用。
image.png
import React, { useRef, forwardRef, useImperativeHandle } from 'react'
const HYInput = forwardRef((props, ref) => {
// inputRef在整个生命周期中应该是不变的
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}), [inputRef.current]);
return <input ref={inputRef} type="text" />
})
export default function UseImperativeHandleHookDemo() {
const inputRef = useRef();
return (
<div>
<HYInput ref={inputRef} />
<button onClick={e => inputRef.current.focus()}>聚焦</button>
</div>
)
}


