• React学习三大属性之ref属性


    一是什么

    二如何使用

    三 引用场景

    一是什么?

    React中的refs提供了一种方式,允许我们访问dom节点或者是在render方法中创建的react元素。

    它的本质是ReactDOM.render返回的组件实例,如果是渲染组件返回的就是组件实例,如果是渲染DOM,然回的就是dom节点。

    二如何使用?

    创建ref的形式有三种:

    1.传入字符串,使用的时候通过 this.refs.传入的字符串 的格式来获取对应的元素,如下:

    <!DOCTYPE html>
    <html>
        <head>
            <title>字符串形式的ref</title>
        </head>
    
        <body>
            <!-- 1.创建一个容器 -->
            <div id="test"></div>
            <!-- 2.导入核心包,必须按照顺序来导入 -->
            <script type="text/javascript" src="../js/react.development.js"></script>
            <script
                type="text/javascript"
                src="../js/react-dom.development.js"
            ></script>
            <script type="text/javascript" src="../js/babel.min.js"></script>
    
            <div id="test"></div>
    
            <!-- 3.编写代码:注意使用的type是text/babel -->
            <!-- React里面的是使用refs,Vue里面是使用$refs,refs拿的是真实的dom节点,而不是虚拟的dom -->
            <!-- 字符串形式的ref并不推荐使用,因为效率问题,可能在后面的版本中弃用 -->
            <script type="text/babel">
                class Dome extends React.Component {
                    // 注意如果要将方法里面的this绑定到组件实例上,需要的格式是使用=号加上箭头函数
                    showData1 = () => {
                        alert(this.refs.input1.value)
                    }
                    showData2 = () => {
                        alert(this.refs.input2.value)
                    }
                    render() {
                        return (
                            <div>
                                <input type='text' ref='input1' />
                                {/*jsx里面的事件和原生的有些不同,原生的是onclick ,jsx里面的是onClick*/}
                                <button ref='button1' onClick={this.showData1}>
                                    点击我显示输入框的数据
                                </button>
                                <input
                                    type='text'
                                    ref='input2'
                                    placeholder='失去焦点显示数据'
                                    onBlur={this.showData2}
                                />
                            </div>
                        )
                    }
                }
                ReactDOM.render(<Dome />, document.getElementById('test'))
            </script>
        </body>
    </html>

    2.传入对象,对象是通过 React.createRef() 方法创建出来的,一个对象只能包含一个dom,使用时候获取到创建的对象中存在current属性就是对应的元素,如下:

    <!DOCTYPE html>
    <html>
        <head>
            <title>字符串形式的ref</title>
        </head>
    
        <body>
            <!-- 1.创建一个容器 -->
            <div id="test"></div>
            <!-- 2.导入核心包,必须按照顺序来导入 -->
            <script type="text/javascript" src="../js/react.development.js"></script>
            <script
                type="text/javascript"
                src="../js/react-dom.development.js"
            ></script>
            <script type="text/javascript" src="../js/babel.min.js"></script>
    
            <div id="test"></div>
    
            <script type="text/babel">
                class Dome extends React.Component {
                    myRef1 = React.createRef() // 创建一个存放dom的ref盒子,但是一个只能存放一个dom,如果多次使用同一个,后面的会覆盖前面的
                    myRef2 = React.createRef()
                    showData1 = () => {
                        let input = this.myRef1.current
                        alert(input.value)
                    }
                    showData2 = () => {
                        let input = this.myRef2.current
                        alert(input.value)
                    }
                    render() {
                        return (
                            <div>
                                <input type='text' ref={this.myRef1} />
                                <button onClick={this.showData1}>点击我显示输入框的数据</button>
                                <input
                                    type='text'
                                    ref={this.myRef2}
                                    placeholder='失去焦点显示数据'
                                    onBlur={this.showData2}
                                />
                            </div>
                        )
                    }
                }
                ReactDOM.render(<Dome />, document.getElementById('test'))
            </script>
        </body>
    </html>

    3.传入回调函数,该函数会在DOM挂载的时候进行回调,这个函数会传入一个元素对象,可以自己保存,使用的时候,直接拿到之前保存的元素对象就可以了

    <!DOCTYPE html>
    <html>
        <head>
            <title>字符串形式的ref</title>
        </head>
    
        <body>
            <!-- 1.创建一个容器 -->
            <div id="test"></div>
            <!-- 2.导入核心包,必须按照顺序来导入 -->
            <script type="text/javascript" src="../js/react.development.js"></script>
            <script
                type="text/javascript"
                src="../js/react-dom.development.js"
            ></script>
            <script type="text/javascript" src="../js/babel.min.js"></script>
    
            <div id="test"></div>
    
            <!-- 3.编写代码:注意使用的type是text/babel -->
            <!-- React里面的是使用refs,Vue里面是使用$refs,refs拿的是真实的dom节点,而不是虚拟的dom -->
            <script type="text/babel">
                class Dome extends React.Component {
                    // 注意如果要将方法里面的this绑定到组件实例上,需要的格式是使用=号加上箭头函数
                    showData1 = () => {
                        let { input1 } = this // 注意:这个时候是从当前组件实例上拿去dom节点,而而不是从refs上
                        alert(input1.value)
                    }
                    showData2 = () => {
                        let { input2 } = this // 注意:这个时候是从当前组件实例上拿去dom节点,而而不是从refs上
                        alert(input2.value)
                    }
                    render() {
                        return (
                            <div>
                                {/*
                                    回调形式的ref
                                        c是当前的dom节点,将当前节点赋值给组件实例的input1上,注意这里的this的是组件实例
                                 */}
                                <input type='text' ref={(c) => (this.input1 = c)} />
                                {/*jsx里面的事件和原生的有些不同,原生的是onclick ,jsx里面的是onClick*/}
                                <button onClick={this.showData1}>点击我显示输入框的数据</button>
                                <input
                                    type='text'
                                    ref={(c) => (this.input2 = c)}
                                    placeholder='失去焦点显示数据'
                                    onBlur={this.showData2}
                                />
                            </div>
                        )
                    }
                }
                ReactDOM.render(<Dome />, document.getElementById('test'))
            </script>
        </body>
    </html>

    如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。

    4传入hook,hook是通过useRef()方式来创建的,使用时候通过生成hook对象的current属性就是对应的元素。(Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。React的三大特性ref,state,props其中的ref和state是类式组件特有的,而函数式组件式没有的

    function App(props) {
       const ref = useRef()
           return (
                <div>
                    <div ref={myRef}>1111</div>
                </div>
            )
    }

    获取ref属性也式通过hook对象的current属性来获取。

    const node = myref.current;

    需要注意的是:不能在函数式组件上使用ref属性,因为他们并没有实例。

    三 应用场景?

    过多的使用refs,会使组件的实例或者式DOM结构暴露,违反了封装组件的原则。

    例如,在Dialog组件里面暴露了open和close方法,通常我们可以传递一个isOpen属性来控制弹窗的显示

    下面的场景可以使用refs:

    (1)对dom元素的焦点控制,内容选择,控制。

    (2)对dom元素的内容设置和媒体播放

    (3)对dom元素的操作和对组件的实例的操作

    (4) 集成第三方的DOM库

  • 相关阅读:
    powerdesigner向MySQL导入数据
    基础数据结构-二叉树-计算二叉树的叶子结点数
    基础数据结构-二叉树-二叉树构建与先中后序遍历
    基础数据结构-串-KMP算法
    基础数据结构-堆栈-拓展:括号匹配
    基础数据结构-堆栈-拓展:行编辑
    基础数据结构-堆栈-逆序输出(理解栈的概念)
    基础数据结构-线性表-单链表的结点交换
    基础数据结构-线性表-单链表的合并操作
    基础数据结构-线性表-单链表实现
  • 原文地址:https://www.cnblogs.com/zhilili/p/16102376.html
Copyright © 2020-2023  润新知