[React] ref 是如何拿到函数组件的实例【热度: 881】

使用forwordRef

input单独封装成一个组件TextInput

const TextInput =  React.forwardRef((props,ref) => {
  return <input ref={ref}></input>
})

TextInputWithFocusButton调用它

function TextInputWithFocusButton() {
  // 关键代码
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // 关键代码,`current` 指向已挂载到 DOM 上的文本输入元素
    inputEl.current.focus();
  };
  return (
    <>
      // 关键代码
      <TextInput ref={inputEl}></TextInput>
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

useImperativeHandle

有时候,我们可能不想将整个子组件暴露给父组件,而只是暴露出父组件需要的值或者方法,这样可以让代码更加明确。而useImperativeHandle Api就是帮助我们做这件事的。

const TextInput =  forwardRef((props,ref) => {
  const inputRef = useRef();
  // 关键代码
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} />
})


function TextInputWithFocusButton() {
  // 关键代码
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // 关键代码,`current` 指向已挂载到 DOM 上的文本输入元素
    inputEl.current.focus();
  };
  return (
    <>
      // 关键代码
      <TextInput ref={inputEl}></TextInput>
      <button onClick={onButtonClick}>
          Focus the input
      </button>
    </>
  );
}

也可以使用current.focus()来做input聚焦。

这里要注意的是,子组件TextInput中的useRef对象,只是用来获取input元素的,大家不要和父组件的useRef混淆了。