React hooks中ref、forwardRef、useImperativeHandle的结合使用

ref:用来绑定到HTML元素或者组件上,获取其DOM;

forwardRef:帮助子组件拿到父组件中子组件上面绑定的ref,绑定到自己的某一个元素中。这样就将子组件的DOM直接暴露给了父组件。这种方式存在的弊端:

        1. 直接暴露给父组件带来的问题是某些情况的不可控
        2. 父组件可以拿到DOM后进行任意的操作
        3. 只是希望父组件可以操作某些方法,并不希望它随意操作其他方法

useImperativeHandle:减少暴露给父组件获取的DOM元素属性, 只暴露给父组件需要用到的DOM方法。有两个参数:

        1. 参数1: 父组件传递的ref属性
        2. 参数2: 函数,返回一个对象,可在父组件中通过ref.current调用该对象中的方法

目录结构如下:

 

代码如下:

App.js:

import './App.css';
import ChangeRef from './changeRef/ChangeRef'

function App() {
  return (
    <ChangeRef />
  );
}

export default App;

ChangeRef.js(父组件):

//父组件
import React, { useRef } from "react";
import Child from "./ChangeRefChild";

const ChangeRef = () => {
  const childRef= useRef();  // 组件的ref

  return (
    <div>
      <button
        onClick={() => {
          console.log(childRef.current);
          childRef.current.focus()  // 获取子组件暴露的focus事件
          childRef.current.getData(345)  // 给子组件的getData函数传参
        }}
      >
        聚焦input
      </button>
      <Child ref={childRef} a={11}></Child>
    </div>
  );
};

export default ChangeRef;

ChangeRefChild.js(子组件):

import React, {useState, forwardRef, useImperativeHandle, useRef} from 'react'

 const ChangeRefChild =  forwardRef((props, ref) => {
   console.log(props, ref);  // {a: 11} {current: undefined}

   const inputRef = useRef();

   const [text, setText] = useState('123');

   useImperativeHandle(ref, () => ({
     focus: () => {
      inputRef.current.focus();
     },
     getData: (abc) => {
       console.log(abc);
       setText(abc)
     }
   }))
  return (
    <>
      <input type="text" ref={inputRef} />
      <p>{text}</p>
    </>
    
  )
})

export default ChangeRefChild

运行结果:

 点击按钮后:

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值