HOC: forwardRef, useImperativeHandle DEMO

import React, { useRef, forwardRef, useImperativeHandle  } from "react";
import "./style.css";

const WrapInput = forwardRef((props, ref) => {
  const inputRef = useRef()

  // 作用: 减少父组件获取的DOM元素属性,只暴露给父组件需要用到的DOM方法
  // 参数1: 父组件传递的ref属性
  // 参数2: 返回一个对象,父组件通过ref.current调用对象中方法
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus()
    }
  })) 

  return <>
    <span>测试:</span>  <input type="text" ref={inputRef} value=""/>
  </>
})

export default function App() {
  const inputRef = useRef()

  // useImperativeHandle 主要作用:用于减少父组件中通过forward+useRef获取子组件DOM元素暴露的属性过多
  // 为什么使用: 因为使用forward+useRef获取子函数式组件DOM时,获取到的dom属性暴露的太多了
  // 解决: 使用uesImperativeHandle解决,在子函数式组件中定义父组件需要进行DOM操作,减少获取DOM暴露的属性过多

  return (
    <div>
      <WrapInput ref={inputRef}/>  
      <button onClick={() => inputRef.current.focus()}>点击聚焦</button>
    </div>
  );
}

parent Component use Child function

import React, { useImperativeHandle } from 'react';
import './style.css';

export default function App() {
  const ChildRef = React.createRef();
  return (
    <div>
      <button
        onClick={() => {
          ChildRef.current.hi();
        }}
      >
        dianwo
      </button>
      <Child onRef={ChildRef} />
    </div>
  );
}

const Child = (props) => {
  useImperativeHandle(props.onRef, () => {
    return {
      hi: () => console.log('hi'),
    };
  });

  return <div></div>;
};
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
import './style.css';

export default function App() {
  const ChildRef = useRef();
  return (
    <div>
      <button
        onClick={() => {
          ChildRef.current.hi();
        }}
      >
        dianwo
      </button>
      <Child ref={ChildRef} />
    </div>
  );
}

const Child = forwardRef((props, ref) => {
  useImperativeHandle(ref, () => {
    return {
      hi: () => console.log('hi'),
    };
  });

  return <div></div>;
})