Refs

198 阅读2分钟

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

  1. 通过React.createRef()方式创建

    当ref被床底给render中的元素时,对该节点的引用,可以在ref的current属性中被访问const node = this.myRef.current

    • 当属性是HEML元素时,构造函数中使用React.createRef()方式创建的ref接收底层DOM元素作为其current属性

    • 当ref属性用于定义class组件时,ref对象接收组件的挂载实例作为其current属性

    • 不能在函数组件上使用ref,因为它没有实例

  2. 通过回调方式创建

    这个函数中接受React组件实例或HTML DOM元素作为参数,以使它们能在其他地方可以被访问

补充

  1. 在函数组件中内部使用ref
function CustomTextInput(props) {
    const textInput = useTef(null);
    function handleClick() {
        this.Input.current.focus();
    }
    
    return (
        <>
            <input type='text' ref={textInput}/>
            <input onClic={handleClick}/>
        </>
    )
}
  1. 可以利用转发功能实现在Function上使用ref