📒REACT笔记👉👉👉Refs

REACT的Refs

REACT的Refs学完了,还记得多少呢...

首先,我们有时候需要获取render方法里的DOM元素、组件实例,Refs则提供了这种能力。但是话说回来,那我们为什么需要获取DOM呢,大概有两点:

0️⃣ 管理焦点/文本选择/媒体播放

1️⃣ 集成第三方DOM库(如jQuery插件等)

如何创建一个Refs对象?创建一个Refs对象其实很简单,我们可以用16.3版本开始引入的React.createRef来创建,React.createRef方法执行生成的Refs对象拥有current属性,该属性指向DOM元素和组件的实例。创建完Ref对象还不够,我们还得把这个Ref对象传递给我们想获取的DOM元素/类组件元素才可以:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Component extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  handleClick = () => {
    if (this.inputRef) {
      this.inputRef.current.focus();
    }
  }

  render() {
    return (
      <>
        <div onClick={this.handleClick}/>
        <input type='input'  ref={this.inpiutRef}/>
      </>
    )
  }
}

🙅‍♂️🙅‍♂️🙅‍♂️ 需要注意的是,我们无法将Ref对象传递给函数式组件元素,就算你传递了,也不会有任何效果,因为函数式组件没有实例!

除了React.createRef以外,我们还可以使用回调函数的方式创建Ref对象:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Component extend React.Component {
  constructor(props) {
    this.inputRef = null;
  }

  setInputRef = ref => this.inputRef = ref;

  render() {
    return <input type='text' ref={this.setInputRef}>
  }
}

🙅‍♂️🙅‍♂️🙅‍♂️ 这块需要注意的点在于不要使用内联函数来创建Refs对象: <div ref={ref ⇒ this.divRef = ref;} />,这种方式在组件更新时可能会被执行两次,Ref对象会存在current为null的情况出现。

我们最后介绍一种String Refs方式来创建Refs对象,<div ref='divRefs' />,然后可以通过this.refs.divRefs获取到,但是String Refs实现上有些问题,且会在后续的版本中被移除,所以强烈不推荐使用。

最后一个知识点我其实没看懂,大概就是父级组件有时需要操作子级组件内的DOM元素或者组件元素,REACT文档给我们提供两种解决方案。第一种方案就是:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class ParentComponent extends React.Component {
  construtor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  render() {
    return <ChildComponent inputRef={this.inputRef}/>
  }

}

class ChildComponent extends React.Component {
  render() {
    return <input type='text'  ref={this.props.inputRef}>
  }
}

解释一下上面的代码,inputRef真的只是props,把它传递给子组件,然后子组件通过props拿到传递下来的inputRef,接着把他传递给目标DOM元素仅此而已!这种方式的使用场景是你的React版本低于16.3,因为16.3以下的版本不支持React.forwardRef (我的意思是这种方法在哪个版本都可以使用,但是既然React给我们提供了React.forwardRef,所以我们应该尽量使用React.forwardRef) ,接下来我们就介绍通过React.forwardRef来获取子组件内部的元素的方法。

比如说我现在有一个FancyButton组件,我需要获取到FancyButton组件内的button元素

1
2
3
function FancyButton({children}) {
  return <button classname='fancybutton'>{children} </button>
}

这时候就可以利用React.forwardRef:

1
2
3
4
5
6
const FancyButton = React.forwardRef((props, ref) => {
  return <button classname='fancybutton' ref={ref}>{children} </button>
});

const buttonRef = React.createRef();
<FancyButton ref={buttonRef}>就是这样简单</FancyButton>

事实上,就是这么简单,通过这样的方式,我们就可以在父组件拿到子组件的DOM元素了!不过官方文档的语气好像在说React.forwardRef似乎会引发意想不到的问题,所以如果是我的话,我还是倾向于 把ref通过props传递下来的方式😂。

打这么多字累死了,基本上全程是copy from document,抄文档。没有参考价值,纯粹个人用来加深印象!

拜拜👋

updatedupdated2020-07-062020-07-06