useImperativeHandle可以让你在使用ref时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用ref这样的命令式代码。useImperativeHandle应当与forwardRef一起使用。
    我们先来回顾一下ref和forwardRef结合使用:

    • 通过forwardRef可以将ref转发给子组件
    • 子组件拿到父组件创建的ref, 绑定到自己的某一个元素中 ```javascript import React, { useRef, forwardRef } from ‘react’

    // forwardRef可以将ref转发给子组件 const JMInput = forwardRef((props, ref) => { return })

    export default function ForwardDemo() { // forward用于获取函数式组件DOM元素 const inputRef = useRef() const getFocus = () => { inputRef.current.focus() }

    return (

    ) }

    1. forwardRef的做法本身没有什么问题, 但是我们是**将子组件的DOM直接暴露给了父组件:**
    2. - 直接暴露给父组件带来的问题是某些情况的不可控
    3. - 父组件可以拿到DOM后进行任意的操作
    4. - 我们只是希望父组件可以操作的focus,其他并不希望它随意操作其他方法
    5. <a name="DGBJA"></a>
    6. ## **useImperativeHandle介绍**
    7. ```javascript
    8. useImperativeHandle(ref, createHandle, [deps])
    • 通过useImperativeHandle可以只暴露特定的操作
      • 通过useImperativeHandle的Hook, 将父组件传入的ref和useImperativeHandle第二个参数返回的对象绑定到了一起
      • 所以在父组件中, 调用inputRef.current时, 实际上是返回的对象
    • useImperativeHandle使用简单总结:
      • 作用: 减少暴露给父组件获取的DOM元素属性, 只暴露给父组件需要用到的DOM方法
      • 参数1: 父组件传递的ref属性
      • 参数2: 返回一个对象, 以供给父组件中通过ref.current调用该对象中的方法
        1. import React, { useRef, forwardRef, useImperativeHandle } from 'react'
        2. const JMInput = forwardRef((props, ref) => {
        3. const inputRef = useRef()
        4. // 作用: 减少父组件获取的DOM元素属性,只暴露给父组件需要用到的DOM方法
        5. // 参数1: 父组件传递的ref属性
        6. // 参数2: 返回一个对象,父组件通过ref.current调用对象中方法
        7. useImperativeHandle(ref, () => ({
        8. focus: () => {
        9. inputRef.current.focus()
        10. },
        11. }))
        12. return <input type="text" ref={inputRef} />
        13. })
        14. export default function ImperativeHandleDemo() {
        15. // useImperativeHandle 主要作用:用于减少父组件中通过forward+useRef获取子组件DOM元素暴露的属性过多
        16. // 为什么使用: 因为使用forward+useRef获取子函数式组件DOM时,获取到的dom属性暴露的太多了
        17. // 解决: 使用uesImperativeHandle解决,在子函数式组件中定义父组件需要进行DOM操作,减少获取DOM暴露的属性过多
        18. const inputRef = useRef()
        19. return (
        20. <div>
        21. <button onClick={() => inputRef.current.focus()}>聚焦</button>
        22. <JMInput ref={inputRef} />
        23. </div>
        24. )
        25. }