images.png

Refs

下面是几个适合使用 refs 的情况:

管理焦点,文本选择或媒体播放。
触发强制动画。
集成第三方 DOM 库。

上面是官方对Refs使用场景的描述,ref本意为“来源”,我觉得可以简单认为相当于原生中的id,只不过react尽量不操作dom

容器形式的Ref

先在类组件中创建一个ref容器

myRef = React.createRef();

然后就可以在jsx中使用该容器

<input ref={this.myRef} placeholder="输入框1"></input>
<button onClick={this.handleClick}>提交</button>

最后当按钮被点击的时候,就可以通过容器取值

handleClick = () => {
    console.log(this.myRef.current.value);
  }

需要注意的是容器是专人专用的,例如当一个容器被多个input使用时,默认最后一个有效。
下面的程序演示了该场景:
当我们在前两个输入框输入值时,鼠标移开,失去焦点,触发onBlur事件,但是输入框的value却不能被正常打印,但最有一个输入框却有效。

class App extends React.Component {
  constructor(props) {
    super(props)
    console.log(this.props);
  }
  // 创建一个ref容器
  myRef = React.createRef();

  handleBlur = () => {
    console.log(this.myRef.current.value);
  }

  handleClick = e => {
    console.log(e);
  }

  render(){
    return (
      <div>
        <input ref={this.myRef} onBlur={this.handleBlur} placeholder="输入框1"></input><p/>
        <input ref={this.myRef} onBlur={this.handleBlur} placeholder="输入框2"></input><p/>
        <input ref={this.myRef} onBlur={this.handleBlur} placeholder="输入框3"></input><p/>
      </div>
    )
  }
}

回调形式的Refs

1. jsx中的内联回调

这种是开发中常用的回调ref方式,该语句将当前节点赋值给类的属性input1

<input ref={ c => {this.input1 = c}} onBlur={this.handleBlur} placeholder="输入框1"></input>

处理onBlur事件时,可以直接打印this.input1

handleBlur = () => {
    console.log(this.input1.value);
  }

2.另一形式的回调

jsx中这样写

<input ref={this.myRef2} onBlur={this.handleBlur} placeholder="输入框0"></input>

类组件中

myRef2 = c => {
    this.input2 = c;
  }

以上方法和内联形式效果一致,但有个细微的差别。

如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的

所以说,还是用第一种回调方法比较好。

过时的方法 String类型的ref

这种方法定义ref比较简单暴力,但是官方已经不再推荐,官方推荐使用Refs容器的方法进行定义refs。

仅有一条评论

  1. echozh echozh

    ref 应该是对一个值保持引用

添加新评论