什么是Refs
ref :reference参考,
Refs 引用一部分真实的DOM,我们可以通过这个引用直接操作DOM
组件并不是真是的DOM,而是存在于内存中的一种数据结构,叫做虚拟DOM,当虚拟DOM插入文档后才会变成真的DOM。根据React的
diff算法
,会将真实DOM与虚拟DOM进行比较,文档只会重新渲染改变的部分,这样可以很大程度上节省性能。
值得注意的是,this.ref返回的的是真实的DOM节点,所以必须得虚拟DOM插入文档后才能使用,否则会报错
与props不同的是
-
props主要用于父组件与子组件之间的通信,并不能直接操作子组件里面的DOM,
-
props不可更改,而refs可以强制更改
-
props在组件还是虚拟DOM的时候就可以使用了,但是Refs引用的是真实的DOM,也就是组件
componentDidMount
后 -
Ref属性指向的节点不能是函数组件,因为通过ref获得的DOM包含了生命周期和state,但是在函数组件中,可以通过ref指向类组件或者DOM节点
function MyFunctionComponent(){ return <div>1</div> } class Child extends React.Component{ constructor(props){ super(props); this.myRef=React.createRef(); } render(){ return <MyFunctionComponent ref={this.myRef}/> //报错Warning: Stateless function components //cannot be given refs. Attempts to access this //ref will fail. } }
-
官方提倡多用props,不要滥用Refs
解决的问题
为了能让父组件直接操作子组件中的元素
import React, {Component} from 'react';
function Child(props) {
return <button>{props.children}</button>
}
class Parent extends Component {
constructor(props, context) {
super(props, context);
this.r = React.createRef()
}
render() {
return <Child ref={this.r}>Click me!!</Child>
}
}
export default Parent;
这里的this.r
拿到的是子组件Child
,而不是子组件中的input
,就不能在父组件上直接让子组件的input获得焦点
this.r.current.focus() //报错
什么时候使用Refs
下面是几个适合使用 refs 的情况:
- 管理焦点,文本选择或媒体播放。
- 触发强制动画。
- 集成第三方 DOM 库。
避免使用 refs 来做任何可以通过声明式实现来完成的事情。
当你想使用refs时,想想是否可以用state代替。最适合设置state的地方是在层级中较高的位置设置。
举个例子,避免在 Dialog 组件里暴露 open() 和 close() 方法,最好传递 isOpen 属性。