美文网首页
useImperativeHandle

useImperativeHandle

作者: 未路过 | 来源:发表于2022-11-05 10:45 被阅读0次
image.png
import React, { forwardRef, memo, useRef } from "react";

/* 
如果父组件想直接控制子组件的dom元素
 通过forwardRef可以将ref转发到子组件;
 子组件拿到父组件中创建的ref,绑定到自己的某一个元素中;
*/
const Home = memo(
  forwardRef((props, ref) => {
    return (
      <div>
        <h2>Home组件</h2>
        <input type="text" ref={ref}></input>
      </div>
    );
  })
);

const App = memo(() => {
  const appInputRef = useRef();
  const handleDOM = () => {
    console.log(appInputRef.current.value); //直接拿到了子组件的input元素
    //可以做任何操作
    appInputRef.current.value = "app 修改了";
  };
  return (
    <div>
      <h2>APP</h2>
      <Home ref={appInputRef}></Home>
      <div>
        <button onClick={handleDOM}>DOM操作</button>
      </div>
    </div>
  );
});

export default App;

担心,把整个input绑定给父组件,担心父组件做一些不好的操作,随意修改我的值之类的。
我们想给父组件一些权限,比如只能获取子组件的值,只能获取焦点之类的,不能修改我的内容

◼ forwardRef的做法本身没有什么问题,但是我们是将子组件的DOM直接暴露给了父组件:
 直接暴露给父组件带来的问题是某些情况的不可控;
 父组件可以拿到DOM后进行任意的操作;
 但是,事实上在上面的案例中,我们只是希望父组件可以操作的focus,其他并不希望它随意操作;。

import React, { forwardRef, memo, useImperativeHandle, useRef } from "react";

/* 
如果父组件想直接控制子组件的dom元素
 通过forwardRef可以将ref转发到子组件;
 子组件拿到父组件中创建的ref,绑定到自己的某一个元素中;
*/
const Home = memo(
  forwardRef((props, ref) => {
    const homeInputRef = useRef();
    useImperativeHandle(ref, () => {
//父组件拿到的appInputRef.current就是这个对象。
      return {
        focus() {
          console.log("focus");
          homeInputRef.current.focus();
        },
        getValue() {
          console.log("get value");
          return homeInputRef.current.value;
        },
        setValue(value) {
          homeInputRef.current.value = value;
        },
      };
    });
    return (
      <div>
        <h2>Home组件</h2>
        <input type="text" ref={homeInputRef}></input>
      </div>
    );
  })
);

const App = memo(() => {
  const appInputRef = useRef();
  const handleDOM = () => {
    //只能做允许的操作
    appInputRef.current.focus();
    console.log(appInputRef.current.getValue());
  };
  return (
    <div>
      <h2>APP</h2>
      <Home ref={appInputRef}></Home>
      <div>
        <button onClick={handleDOM}>DOM操作</button>
      </div>
    </div>
  );
});

export default App;

通过useImperativeHandle可以值暴露固定的操作:
 通过useImperativeHandle的Hook,将传入的ref和useImperativeHandle第二个参数返回的对象绑定到了一起;
 所以在父组件中,使用 inputRef.current时,实际上使用的是返回的对象;
 比如我调用了 focus函数,甚至可以调用 printHello函数;

相关文章

网友评论

      本文标题:useImperativeHandle

      本文链接:https://www.haomeiwen.com/subject/gfnytdtx.html