useImperativeHandle使用

useImperativeHandle可以让你在使用ref时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用ref这样的命令式代码。useImperativeHandle应当与forwardRef一起使用。

介绍:

useImperativeHandle(ref, createHandle, [deps])

  • 通过useImperativeHandle可以只暴露特定的操作
  • 通过useImperativeHandle的Hook, 将父组件传入的ref和useImperativeHandle第二个参数返回的对象绑定到了一起
  • 所以在父组件中, 调用inputRef.current时, 实际上是返回的对象

使用:

  1. 父组件使用useRef(或createRef)创建一个ref对象,将这个ref对象赋给子组件的ref属性
  2. 子组件使用forwardRef包装自己,允许作为函数组件的自己使用ref。然后使用useImperativeHandle钩子函数,在该钩子函数的第二个函数参数中返回一些状态或方法,这个被返回的状态或方法就可以被父组件访问到。
  3. 父组件使用创建的ref对象的current属性获取子组件暴露出的状态或方法。

总结:

  • 作用: 减少暴露给父组件获取的DOM元素属性, 只暴露给父组件需要用到的DOM方法
  • 参数1: 父组件传递的ref属性
  • 参数2: 返回一个对象, 以供给父组件中通过ref.current调用该对象中的方法

示例代码:

import React, { useRef, useImperativeHandle } from 'react';
import ReactDOM from 'react-dom';

const FancyInput = React.forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} type="text" />
});

const App = props => {
  const fancyInputRef = useRef();
  return (
    <div>
      <FancyInput ref={fancyInputRef} />
      <button
        onClick={() => fancyInputRef.current.focus()} // 调用子组件的方法
      >
        父组件调用子组件的 focus
      </button>
    </div>
  )
}
ReactDOM.render(<App />, root);

OR ==> 

子组件: 

/**
 * 图片预览组件 使用参考:
 */
import React, { useState, useImperativeHandle } from "react";
import { Dialog, Grid } from "@alifd/next";
const { Row } = Grid;
const ImagePreviewModal: React.FC<any> = ({ style, cRef }: { style: {[key: string]: string}, cRef: any }) => {
  const [visible, setVisible] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const [url, setUrl] = useState<string>("");

  useImperativeHandle(cRef, () => ({
    onClose: () => setVisible(false),
    open: (url: string) => {
      setVisible(true);
      setLoading(false);
      setUrl(url);
    }
  }))


  return (
    <Dialog
      footerActions={["cancel"]}
      title={`图片预览`}
      visible={visible}
      onCancel={() => setVisible(false)}
      onClose={() => setVisible(false)}
      okProps={{ loading: loading }}
      style={style}
    >
      <Row>
        <img src={url} style={{ width: "100%" }} />
      </Row>
    </Dialog>
  );
};

export default ImagePreviewModal;

父组件:

import React, { useEffect, useState, useRef } from "react";
import ImgPreview from "../../components/imgPreviewModal";

const Details: React.FC<any> = (props) => {
    const imgPreview = useRef();
    return (
        <div>
            <img
                className="ps-form-img"
                src={'imgUrl'}
                alt=""
                onClick={() => {
                  imgPreview.current.open('imgUrl');
                }}
            />
            <ImgPreview cRef={imgPreview} style={{ width: "750px" }} />
        </div>
    );

};
export default Details;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
useImperativeHandle是React的一个自定义Hook函数,它可以在使用ref时自定义暴露给父组件的实例值。通常情况下,我们应该避免使用ref这样的命令式代码,而是使用更加声明式的方法进行组件间的通信。然而,在某些情况下,我们可能需要在父组件中获取子组件的一些内部状态或方法,这时就可以使用useImperativeHandle配合forwardRef来实现这个功能。 useImperativeHandle使用方法如下: ```javascript useImperativeHandle(ref, createHandle, [deps]) ``` 其中,ref是一个React引用对象,createHandle是一个函数,用于定义要暴露给父组件的实例值,deps是一个可选的依赖数组。 在父组件中,可以通过ref来获取子组件内部暴露的实例值,从而实现父子组件之间的通信。通过useImperativeHandle,父组件可以一次性获取到多个标签元素或其他子组件内部的状态或方法。 在子组件中,需要使用React的useState、useImperativeHandle等Hook函数来定义内部状态或实例值,并将其暴露给父组件使用。在useImperativeHandle中,可以返回一个对象,该对象包含了需要暴露给父组件的实例值。 总而言之,useImperativeHandle是一个可以让父组件获取子组件内部状态或方法的自定义Hook函数,通过配合forwardRef使用,可以实现父子组件之间的通信。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [useImperativeHandle使用实例](https://blog.csdn.net/WJLcomeon/article/details/123246152)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [前端必读2.0:如何在React 中使用SpreadJS导入和导出 Excel 文件](https://blog.csdn.net/web22050702/article/details/127797298)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值