Refs提供了一种方式,允许访问DOM节点或在render方法中创建的React元素
为什么提供
典型的React数据流中,props是父子组件交互的唯一方式,要修改一个子组件,需要使用新的props来渲染它,但在某些情况下,需要强制修改子组件,被修改的子组件可能是一个React实例也可能是一个DOM元素。
创建Refs
React.createRef()创建
Refs是使用React.createRef()创建的并通过ref属性附加到React元素。在构造组件时,通常将Refs分配给实例属性,以便可以在整个组件中引用它们。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />
}
}
可以为DOM元素和class组件添加Ref
回调函数创建
不同于传递creatRef()创建的ref属性,你会传递一个函数,这个函数中接受React组件实例或HTML DOM元素作为参数,以使它们能在其他地方可以被访问
// 这个例子使用ref回调函数,在实例的属性中存储对DOM节点的引用
class CustomTextInput extends Teact.Component {
constructor(props) {
super(props) {
this.textInput = null;
this.setTextInputRef = element => {
this.textInput = element;
}
}
}
render() {
// 使用‘ref’回调函数将text输入框DOM节点的引用存储到React实例上(比如this.textInput)
return <input ref={this.setTextInputRef} />
}
}
还可以内联的方式,不过不推荐
<input ref={ref => this.textInput = ref} />,因为如果是回调函数是内联方式定义的,在更新过程中它会被执行两次,第一次传入参数是null,然后第二次会传入参数DOM元素,这是因为在每次渲染时,会创建一个新的函数实例,所以React会清空旧的ref并设置新的。
字符串refs老版本创建方式不推荐使用
<input ref="input" />
// 访问
this.refs.input
访问Refs
-
通过React.createRef()方式创建
当ref被床底给render中的元素时,对该节点的引用,可以在ref的current属性中被访问
const node = this.myRef.current-
当属性是HEML元素时,构造函数中使用React.createRef()方式创建的ref接收底层DOM元素作为其current属性
-
当ref属性用于定义class组件时,ref对象接收组件的挂载实例作为其current属性
-
不能在函数组件上使用ref,因为它没有实例
-
-
通过回调方式创建
这个函数中接受React组件实例或HTML DOM元素作为参数,以使它们能在其他地方可以被访问
补充
- 在函数组件中内部使用ref
function CustomTextInput(props) {
const textInput = useTef(null);
function handleClick() {
this.Input.current.focus();
}
return (
<>
<input type='text' ref={textInput}/>
<input onClic={handleClick}/>
</>
)
}
-
可以利用转发功能实现在Function上使用ref