react学习教程入门六(组件三大核心属性之refs)

React 支持一种非常特殊的属性 ref,你可以用来绑定到 render() 输出的任何组件上。这个特殊的属性允许你引用 render() 返回的相应的支撑实例。这样就可以确保在任何时间总是拿到正确的实例。

使用方法

使用方式有多种,第一种,最早期的时候也是现在不建议用的,是通过绑定一个 ref 属性到 render 的返回值上:比如定义一个input框标签,如果要获取这个input框,可以通过 ref="input1"进行定义,然后通过 this.refs 获取支撑实例;

完整实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>1_字符串形式的ref</title>
</head>
<body>
    <!-- 准备好一个“容器” -->
    <div id="test"></div>
    
    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <script type="text/babel">
        //创建组件
        class Demo extends React.Component{
            //展示左侧输入框的数据
            showData = ()=>{
                const {input1} = this.refs
                alert(input1.value)
            }
            //展示右侧输入框的数据
            showData2 = ()=>{
                const {input2} = this.refs
                alert(input2.value)
            }
            render(){
                return(
                    <div>
                        <input ref="input1" type="text" placeholder="点击按钮提示数据"/>&nbsp;
                        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                        <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>
                    </div>
                )
            }
        }
        //渲染组件到页面
        ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
    </script>
</body>
</html>

但是我们说了这种方式实际上已经被废弃了,ref后面不再是赋值为一个引号里的字符串,而是要一个表达式,表达式里的定义还可以有两种方式,一种是通过在表达式里使用回调函数来定义和获取refs属性的内容,方式为:ref={c => this.input1 = c } 这是通过把当前节点对象赋值给组件中的this的input1属性,这样赋值之后就变成了组件的一个属性了,自然而然就可以使用了,比如上面的示例就可以完整的改成如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>1_字符串形式的ref</title>
</head>
<body>
    <!-- 准备好一个“容器” -->
    <div id="test"></div>
    
    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <script type="text/babel">
        //创建组件
        class Demo extends React.Component{
            //展示左侧输入框的数据
            showData = ()=>{
                const {input1} = this
                alert(input1.value)
            }
            //展示右侧输入框的数据
            showData2 = ()=>{
                const {input2} = this
                alert(input2.value)
            }
            render(){
                return(
                    <div>
                        <input ref={c => this.input1 = c } type="text" placeholder="点击按钮提示数据"/>&nbsp;
                        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                        <input onBlur={this.showData2} ref={c => this.input2 = c } type="text" placeholder="失去焦点提示数据"/>&nbsp;
                    </div>
                )
            }
        }
        //渲染组件到页面
        ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
    </script>
</body>
</html>

这是ref赋值表达式的其中一种方式,还有一种是通过 React.createRef()方法来获取的,React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的。完整的示例可以变成如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>4_createRef</title>
</head>
<body>
    <!-- 准备好一个“容器” -->
    <div id="test"></div>
    
    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <script type="text/babel">
        //创建组件
        class Demo extends React.Component{
            /* 
                React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的
             */
            myRef = React.createRef()
            myRef2 = React.createRef()
            //展示左侧输入框的数据
            showData = ()=>{
                alert(this.myRef.current.value);
            }
            //展示右侧输入框的数据
            showData2 = ()=>{
                alert(this.myRef2.current.value);
            }
            render(){
                return(
                    <div>
                        <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
                        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                        <input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
                    </div>
                )
            }
        }
        //渲染组件到页面
        ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
    </script>
</body>
</html>

 虽然我们说了上面三种refs的获取方式,但是其实react官方的建议是,能不用ref就不用ref属性,原因是ref实际上是对节点的操作,而react并不推崇我们一直操作dom节点,而且这种写法并不比JavaScript或者jquery有什么高级之处,那么如果我们不用操作节点dom的方式来获取值,应该如何获取值呢,就比如上面的这个例子,其实失去焦点提示数据的这个完全可以用通过事件的获取来获取值,也就是说在onBlur事件,即鼠标离开事件中来获取值,具体的写法是在onBlur={this.showData2}中,传递event事件,然后通过event.target.value来获取。具体的完整代码可以改成如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件处理</title>
</head>
<body>
    <!-- 准备好一个“容器” -->
    <div id="test"></div>
    
    <!-- 引入react核心库 -->
    <script type="text/javascript" src="../js/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script type="text/javascript" src="../js/react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转为js -->
    <script type="text/javascript" src="../js/babel.min.js"></script>

    <script type="text/babel">
        //创建组件
        class Demo extends React.Component{
            /* 
                (1).通过onXxx属性指定事件处理函数(注意大小写)
                        a.React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 —————— 为了更好的兼容性
                        b.React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) ————————为了的高效
                (2).通过event.target得到发生事件的DOM元素对象 ——————————不要过度使用ref
             */
            //创建ref容器
            myRef = React.createRef()
            myRef2 = React.createRef()

            //展示左侧输入框的数据
            showData = (event)=>{
                console.log(event.target);
                alert(this.myRef.current.value);
            }

            //展示右侧输入框的数据
            showData2 = (event)=>{
                alert(event.target.value);
            }

            render(){
                return(
                    <div>
                        <input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
                        <button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
                        <input onBlur={this.showData2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
                    </div>
                )
            }
        }
        //渲染组件到页面
        ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
    </script>
</body>
</html>

但这种事件的获取方式并不是万能的,就像上面点我提示左侧的数据的这个事件,实际上获取不到非本标签内的点击事件,所以refs也有非用不可的地方,只能说不用就尽量不用~

posted @ 2021-03-07 13:27  我只是个扫地的  阅读(227)  评论(0)    收藏  举报