头图

前提知识点

useImperativeHandle常与forwardRefref一起使用,所以需要理解后两者的基础用法。可以通过以下两个示例代码,快速了解refforwardRef的使用方法。

  • Demo1: 在Class和Functional函数中使用ref .该示例展示了ref的用法,同时表明不经过forwardRef封装的子组件,无法将ref传给父组件。
  • Demo2: farwardRef转发ref.该示例展示了farwardRef的用法,父组件ForwardButton成功获取到子组件RefInFunctionalComponentref

useImperativeHandle

官网说

useImperativeHandle customizes the instance value that is exposed to parent components when using ref

怎么理解呢?

当父组件通过forwardRef属性,得到子组件的ref时,它只得到一个可读的对象。而useImperativeHandle配合forwardRef来使用,则给予了修改ref的能力,比如为ref增加自定义方法。

这种在父组件中直接调用子组件ref函数的方法,一点都不React,所以React并不推荐。但是为了方便第三方库的开发,则需要提供这种自定义ref的能力。

我们在Demo2的基础上修改一下代码,看看useImperativeHandle如何工作。

修改子组件RefInFunctionalComponent,新增useImperativeHandle代码块,自定义getContent方法,如下:

const RefInFunctionalComponent = (props, ref) => {
  const innerRef = useRef(null)
  useImperativeHandle(ref, () => ({
    getContent: () => innerRef.current.innerText
  }))
  const handleClick1 = () => {
    console.log(ref.current.innerText)
  }
  return <button ref={innerRef} onClick={handleClick1}>{props.children}</button>
}
const ForwardButton = forwardRef(RefInFunctionalComponent)

在父组件中使用ForwardButton:

const App = () => {
  const ref = useRef(null)
  const handleClick = () => {
    console.log(ref.current.getContent()) // 按钮1
  }
  return (
    <div className="wrapper">
      <ForwardButton ref={ref}>按钮1</ForwardButton>
      <button onClick={handleClick}>获取button1</button>
    </div>
  );
};

Demo3:完整示例代码

参考


jinling
455 声望25 粉丝

RunJS在线编辑器开发者。[链接]