React中如何使用ref

1、React中的ref是用来干什么的?

用来获取组件的dom对象,便于我们想要去操作dom元素

2、如何获取ref并使用

2.1、类组件(使用React.createRef()方法)

import React, { createRef } from 'react'

export default class Test extends React.Component {
    constructor(props) {
        super(props)
        this.testRef = createRef()
    }

    handleClick = () =>{
        console.log(this.testRef.current,'ref')
    }

    render() {
        const array = [
            {key:1,name:'第一个'},
            {key:2,name:'第二个'},
            {key:3,name:'第三个'},
        ]

        return (
            <div ref={this.testRef} style={{background:'#fff',height:'500px',width:'500px'}} onClick={()=>this.handleClick()}>
                <div className='content-wrap'>
                    <ul>
                        {array.map(item => (
                            <li key={item.key}>{item.name}</li>
                        ))}
                    </ul>
                </div>
            </div>
        )
    }
}

当点击的时候即可获得div的dom结构
在这里插入图片描述
获取dom元素可以干嘛呢?例如我们需要前端实现PDF下载功能

<div ref={pdfRefs}>需要下载的页面</div>
<div
	 id="pdf-con"
	  style={{
	      backgroundColor: '#cccccc',
	      opacity: 0
	  }}
/> //
//打印的方法
handlePdfDownload = () => {     
        setTimeout(()=>{
            let targetDom = pdfRefs.current;
            // 获取节点高度,后面为克隆节点设置高度。
            let height = targetDom.height;
            // 克隆节点,默认为false,不复制方法属性,为true是全部复制。
            let cloneDom = targetDom.cloneNode(true);
            // 设置克隆节点的css属性,因为之前的层级为0,我们只需要比被克隆的节点层级低即可。
            cloneDom.style.position = 'absolute';
            cloneDom.style.top = '-100%';
            cloneDom.style.index = '-1';
            cloneDom.style.height = height;
            cloneDom.style.fontSize = '14px';
            // 将克隆节点动态追加到body后面。
            document.getElementById('pdf-con')?.appendChild(cloneDom);
            // 插件生成base64img图片。
            html2Canvas(cloneDom, {
                useCORS: true,
                // 画布开始渲染的y坐标位置
                y: 0
            }).then((canvas) => {
                let contentWidth = canvas.width;
                let contentHeight = canvas.height;
                // 一页pdf显示html页面生成的canvas高度;
                let pageHeight = (contentWidth / 592.28) * 841.89;
                // 未生成pdf的html页面高度
                let leftHeight = contentHeight;
                // 页面偏移
                let position = 0;
                // a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
                let pageData = canvas.toDataURL('image/jpeg', 1.0);
                let pdf = new JsPDF(null, 'pt', 'a4');
                // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
                // 当内容未超过pdf一页显示的范围,无需分页

                // 设置内容图片的尺寸,img是pt单位 已知 1pt/1px = 0.75   pt = (px/scale)* 0.75
                let imgX = contentWidth * 0.75;
                let imgY = contentHeight * 0.75;

                if (leftHeight < pageHeight) {
                    pdf.addImage(pageData, 'JPEG', 0, 0, imgX, imgY);
                } else {
                    while (leftHeight > 0) {
                    pdf.addImage(pageData, 'JPEG', 0, position, imgX, imgY);
                    leftHeight -= pageHeight;
                    // 避免添加空白页
                    position -= 841.89;
                    if (leftHeight > 0) {
                        pdf.addPage();
                    }
                    }
                }
                let nowDate = moment(new Date()).format('YYYY-MM-DD');
                //下载
                pdf.save('打印文件-' + nowDate + '.pdf');
                this.setState({ loadingDown: false });
            });
        })
    };

具体pdf下载功能实现请参考此博客

2.2、类组件(直接在div中使用ref)

<div ref={ref => this.testRef = ref}><div className="sfsfs">测试</div></div>

然后直接使用this.testReft就可以获得这个div的dom结构啦
在这里插入图片描述
可以相对应的去进行一些操作,例如当鼠标移入移出这个div的时候想做一些操作

this.testReft.onmouseover = () => {

}
this.testReft.onmouseout = () => {

}

2.3、函数组件(在普通dom元素上的使用)

注:函数组件本身是不能使用ref的,因为它们没有实例
在函数组件中的普通dom元素上使用ref的步骤如下:

import React, {useEffect,useRef} from 'react' //1.引入useRef
import './index.scss'
import swiper from 'swiper'
import 'swiper/dist/css/swiper.css';

const AntdTest = () => {
    const swiperRef = useRef(null) //2.创建一个ref对象,并将这个ref对象的current属性初始化为null,ref对象的current属性指向的是DOM实例
    
    useEffect(()=>{
        swiperRef.onmouseover = () => { // 4.ref对象的使用,给这个div绑定移入移除事件

        }
        swiperRef.onmouseout = () => {

        }
        console.log(swiperRef,'swiperRef')
    },[])

    return (
        <div className='antdTest'>
            <div className='swiper-container' id='swiper-container1' ref={swiperRef}> //3.将这个ref对象赋值给普通dom元素的ref属性
                <div className='swiper-wrapper'>
                    <div className='swiper-slide'>
                        <div style={{height:200,background:'red'}}>页面一</div>
                    </div>
                    <div className='swiper-slide'>
                        <div style={{height:200,background:'blue'}}>页面二</div>
                    </div>
                    <div className='swiper-slide'>
                        <div style={{height:200,background:'yellow'}}>页面三</div>
                    </div>
                </div>
                <div className='swiper-pagination' id='swiper-pagination1' />
            </div>
        </div>
    )
}

export default AntdTest

打印结果如下:
在这里插入图片描述

2.3、函数组件(直接给ref对象赋值)

 const mapRef= useRef(null)  //1.创建ref对象
 mapRef.current = xxx //2.直接把某个实例对象赋值给ref对象的current属性
 mapRef.current.xxx // 3.可以直接通过ref对象的current属性操作某个实例对象
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值