React中Refs的几种用法

React.createRef()

class CustomTextInput extends React.Component {
    constructor(props) {
        super(props);
        this.textInput = React.createRef();
        this.focusTextInput = this.focusTextInput.bind(this);
    }

    focusTextInput() {
        this.textInput.current.focus();
    }

    render() {
        return (
            <div>
                <input
                    type="text"
                    ref={this.textInput} />
                <input
                    type="button"
                    value="Focus the text input"
                    onClick={this.focusTextInput}
                />
            </div>
        );
    }
}
复制代码

1.创建锚点对象

使用React.createRef()后是创建一个Object对象,这个对象的属性为空,__proto__指向的是Object的原型函数

2.在标签处绑定锚点对象

<input type="text" ref={this.textInput} />
复制代码

渲染后,让this.textInput.current=input,即指向锚点处的DOM标签

3.使用锚点

<input
    type="button"
    value="Focus the text input"
    onClick={this.focusTextInput}
/>
复制代码

点击后触发focusTextInput(),执行函数,内部让锚点处聚焦

Refs相当于锚点,标记一个位置,方便之后直接使用这个位置的DOM

回调Refs

class CustomTextInput extends React.Component {
    constructor(props) {
        super(props);
        this.textInput = null;
        this.focusTextInput = () => {
            // 聚焦
            if (this.textInput){
                this.textInput.focus();
            }
        };
    }

    render() {
        // e就是input标签
        return (
            <div>
                <input
                    type="text"
                    ref={(e)=>{this.textInput=e}}
                />
                <input
                    type="button"
                    value="Focus the text input"
                    onClick={this.focusTextInput}
                />
            </div>
        );
    }
}
复制代码

1.在锚点处创建并绑定对象

<input type="text" ref={(e)=>{this.textInput=e}}/>
复制代码

使用箭头函数的方式,传入的参数e就是此处的DOM标签,那么this.textInput=input注意与上一种方式进行区分,那个是给.current赋值

2.使用锚点

constructor(props) {
    super(props);
    this.textInput = null;
    this.focusTextInput = () => {
        if (this.textInput){
            this.textInput.focus();
        }
    };
}
复制代码

这里将箭头函数直接写在构造器中,用this.focusTextInput指向该箭头函数

这种写法为啥正确,不用bind,这里不纠结,简而言之,就是在构造器中的函数是直接绑定在对象属性上的,而如果单独写成函数则是在它原型链上

Refs转发

// React.forwardRef()方法将ref实例作为其回调函数的第二个参数向下转发给底层DOM组件
const TextInput = React.forwardRef((props, ref) => (
    // 此时inputRef.current=TextInput
    <input type="text" placeholder="请输入表名" ref={ref} />
));
// 创建锚点
const inputRef = React.createRef();
class CustomTextInput extends React.Component {
    handleSave = () => {
        console.log(inputRef.current);
    };

    render() {
        return (
            <div>
                {/* 将ref实例指定给组件TextInput,此时inputRef.current=TextInput */}
                <TextInput ref={inputRef} />
                <button onClick={this.handleSave}>保存</button>
            </div>
        );
    }
}
复制代码

这是一个Refs转发的例子,过程如下:

1.使用 React.createRef() 创建一个ref实例(inputRef);

2.将ref实例指定给组件(TextInput)的ref属性 ;

3.React.forwardRef()方法将ref实例作为其回调函数的第二个参数向下转发给底层DOM组件

4.在外层组件中能够通过 current对象访问DOM节点值。

打印的console.log(inputRef.current);

image.png

说明转发成功,此时全局的inputRef实例(锚点)指向的是这个DOM元素


现在将TextInput组件进行更换,不进行转发

class TextInput extends React.Component{
    render(){
        return <input type="text" placeholder="请输入表名"/>
    }
}
复制代码

打印出来,此时全局的inputRef实例(锚点)指向的是TextInput这个DOM元素

image.png

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享