你的浏览器不支持canvas

Enjoy life!

React - ref

Date: Author: JM

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。

一、refs 和 DOM

1.1 操作DOM的入口 - ref

  • React隔离了大部分DOM,让我们不再需要操作那么多的DOM,例如:事件绑定、添加类名、元素添加内容。
  • react里我们是无法通过document.getElementById之类的方法获取DOM元素的。
  • 但有些场景中,我们仍需要操作DOM,此时React就为我们提供了一个操作DOM的接口(一个特殊的属性) — ref
  • 以下是需要使用ref,即:操作DOM的场景:
    • 焦点处理,文本选择或媒体控制
    • 控制js动画
    • 使用依赖DOM的第三方库

1.2 ref的使用

  • ref属性采用回调函数,这个回调函数在组件被安装或卸载后将会被立刻执行。

  • ref属性被用在了一个HTML元素上,它的回调函数会接收最底层的DOM元素作为它的参数。

1.3 实例 文本框获取焦点

import React, {Component} from "react";

import './style.css';

class Input extends Component {

  handleEvent (event) {
    const value = event.target.value;

    this.props.onChange && this.props.onChange(value); // 通过this.props调用onChange函数
    console.log(`value:${value}`);
    console.log(`this:${this}`);
  }

  focusTextInput () {
      this.input.focus(); // this.input 在ref的回调函数中通过this.input=input获取到了对应的dom元素
  }

  render () {

    return (
      <div className="input-container">
          <input
            onKeyUp={this.handleEvent.bind(this)}
            ref={(input) => {this.input = input; }} // 使用了ref
          />
      </div>
    )
  }
}

export default Input;
  • ref的使用: ref={(input) => {this.input = input; }}
  • 当组件被安装(使用)的的时候,Reactref的回调函数就会返回对应的DOM元素; 当组件被卸载(不被使用)的时候,Reactref的回调函数就会返回null

1.4 Exposing DOM ref to Parent Components

  • 有时候,我们希望通过父组件去访问子组件的DOM节点。
  • 这个想法是不推荐实施的,因为它会破坏了组件的封装性,但是这偶尔会有助于触发焦点或测量子DOM节点的大小或位置。
  • 虽然可以向子组件添加ref,但这不是一个理想的解决方案,因为你只能获取组件实例而不是DOM节点
  • 相反,推荐在子组件中使用props属性,并将其作为ref属性附加到DOM节点。
    • 这允许父代通过中间的组件将其ref回调传递给子节点的DOM节点。
// 子组件
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} /> // ref  props
    </div>
  );
}

// 父组件
class Parent extends React.Component {
  render() {
    return (
      <CustomTextInput
        inputRef={el => this.inputElement = el} //
      />
    );
  }
}
  • Parent传递它的 ref callbackCustomTextInputpropsinputRef
  • 与此同时,CustomTextInput将具有相同功能的作为特别的ref属性传递个<input/>
  • 结果:在Parent中的this.inputElement被设置为与CustomTextInput中的<input>元素相对应的DOM节点。

  • 使用<input>本身的ref属性很重要,因为它告诉React将引用附加到其DOM节点。

1.5 ref的注意事项

  • 1.不能在函数的组件上使用ref,因为他们并不会拥有实例。
function MyComponent () {
    return <Input/>
}

class Parent extends React.Component {
  render () {
    return
      <MyComponent
        ref={(input) => this.input = input;}
      />
  }
}
  • 2.如果真想在函数组件中使用ref,可以引用DOM元素或者一个类组件。
function CustomTextInput (props) {
 // tInput必须在这里被声明,只有这样,ref的回调函数才可以引用它
  let tInput = null;

  function handleClick () {
    input.focus();
  }

  return (
    <div>
      <input
        type="text"
        ref={(input) => { tInput = input; }}
      />
      <input
        type="button"
        value="Focus the text input"
        onClick={handleClick}
      />
    </div>
  )
}

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。