React之refs

1、Refs是什么?

官网Refs解释:Refs 提供了一种方式,允许我们访问DOM 节点或render 方法创建的 React 元素。

2、什么时候使用refs?

1) 管理焦点,文本选择或媒体播放。
对于聚焦和失去焦点,下面举例说明
//原文链接:https://stackoverflow.com/questions/32553158/detect-click-outside-react-component

1 import React, { Component } from 'react';
 2 import PropTypes from 'prop-types';
 3 
 4 /**
 5  * Component that alerts if you click outside of it
 6  */
 7 export default class OutsideAlerter extends Component {
 8     constructor(props) {
 9         super(props);
      //使用 React.createRef() 创建Refs
11         this.wrapperRef = React.createRef();
12         this.setWrapperRef = this.setWrapperRef.bind(this);
13         this.handleClickOutside = this.handleClickOutside.bind(this);
14     }
15 
16     componentDidMount() {
       //只有在组件挂载时才会给current属性传入dom元素
17         document.addEventListener('mousedown', this.handleClickOutside);
18     }
19         //在组件卸载时给current属性传入null值
20     componentWillUnmount() {
21         document.removeEventListener('mousedown', this.handleClickOutside);
22     }
23 
24     /**
25      * Alert if clicked on outside of element
26      */
27     handleClickOutside(event) {
       //此时可以通过创建的Refs的current属性来访问底层dom元素节点(原生dom)
           //当ref属性用于自定义的class组件时,current属性访问的是该组件的挂载实例(此处可以参考下面内容的第四点
28         if (this.wrapperRef.current && !this.wrapperRef.current.contains(event.target)) {
29             alert('You clicked outside of me!');
30         }
31     }
33     render() {
      //通过ref属性将创建的Refs即wrapperRef附加到HTML元素 
34       return <div ref={this.wrapperRef}>{this.props.children}</div>;
 35  } 
 36 } 
 37 
 38 OutsideAlerter.propTypes = { 
 39  children: PropTypes.element.isRequired, 
 40 };

2)触发强制动画。
3)集成第三方 DOM 库。

3、Refs都包含的属性

ref可以调用的属性:current
此时的current就是指Refs访问到的原生dom节点

current可以调用的属性和方法:
如果是访问html元素,此时可以调用原生DOM事件
如果是自定义的class组件,可以直接调用该类组件中的属性或者成员方法

contains()方法:判断某个元素是不是选定元素的子元素或者本身
例如,在实际开发中,要求点击安全域以外的空白地方,实现隐藏当前面板的效果
this.toggleContainer.current.contains(event.target) 具体代码

4、ref 的值根据节点的类型而有所不同,此时可以参考react官网中关于Refs属性讲解

  1. 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
    此时可以通过Refs的current属性直接调用原生dom可以触发的事件原生DOM事件
  2. 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
    此时可以通过ref来访问该类组件中的属性或者成员方法
  3. 默认情况下,你不能在函数组件上使用 ref 属性,因为它们没有实例:

5、高阶组件中的Refs

参考链接:https://juejin.cn/post/6844903809274085389


// 记录状态值变更操作
function logProps(Comp) {
  class LogProps extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('old props:', prevProps);
      console.log('new props:', this.props);
    }
    render() {
      const { forwardedRef, ...rest } = this.props;
      return <Comp ref={ forwardedRef } {...rest} />;
    }
  }
  return React.forwardRef((props, ref) => {
    return <LogProps { ...props } forwardedRef={ ref } />;
  });
}

// 子组件
const BtnComp = React.forwardRef((props, ref) => {
  return (
    <div>
      <button ref={ref} className='btn'>
        { props.children }
      </button>
    </div>
  )
});

// 被logProps包装后返回的新子组件
const NewBtnComp = logProps(BtnComp);


class TestComp extends React.Component {
  constructor(props) {
    super(props);
    this.btnRef = React.createRef();

    this.state = {
      value: '初始化'
    }
  }

  componentDidMount() {
    console.log('ref', this.btnRef);
    console.log('ref', this.btnRef.current.className);
    this.btnRef.current.classList.add('cancel'); // 给BtnComp中的button添加一个class
    this.btnRef.current.focus(); // focus到button元素上
    setTimeout(() => {
      this.setState({
        value: '更新'
      });
    }, 10000);
  }

  render() {
    return (
    //btnRef
      <NewBtnComp ref={this.btnRef}>{this.state.value}</NewBtnComp>
    );
  }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值