zl程序教程

您现在的位置是:首页 >  前端

当前栏目

React:使用Refs的正确姿势,三种方式调用

React 方式 调用 正确 三种 姿势 Refs 使用
2023-09-11 14:22:28 时间

目录

上篇:

前言:

1. 字符串形式的ref

2. 回调形式的ref

关于回调 refs 的说明

3. 最新的使用 React.createRef()

总结


上篇:

React:props常用验证_Jay丶千珏的博客-CSDN博客

前言:

在React中,很典型的父子组件通信方式就是使用props,当时在某些特殊的情况下,我们需要在典型数据流之外强制修改子组件。被修改的子组件可能是一个 React 组件的实例,也可能是一个 DOM 元素。为了更好的解决这个问题,React提供了解决的办法:ref。通过往组件或者dom元素上绑定ref属性,我们可以拿到此实例,以此来解决更多的事情!

关于ref的使用场景,react官方中,是这么说的:

1. 字符串形式的ref

此种形式的写法,最为简单方便快捷,但是很可惜的是,react已经不再建议使用它了,虽然现在的版本还可以用,但是react官方写到,我们不建议使用它,因为 string 类型的 refs 存在 一些问题。它已过时并可能会在未来的版本被移除。但还是能用😁

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel">
    const app = document.getElementById('app')

    class Goods extends React.Component {
        inputClick = () => {
            // 2.点击的时候,直接通过this.refs.xxx进行访问
            const myInput = this.refs.myInput
            alert(myInput.value)
        }

        render() {
            const {inputClick} = this
            return (
                <div>
                    <!-- 1. 在需要获取的组件实例或者dom上直接绑定ref属性 -->
                    <input type="text" ref="myInput"/>
                    <button onClick={inputClick}>点击我输入框聚焦</button>
                </div>
            );
        }
    }

    ReactDOM.render(<Goods/>, app)
</script>
</body>
</html>

2. 回调形式的ref

使用回调函数式创建的 ref 属性,会传递一个函数。这个函数中接受 React 组件实例或 HTML DOM 元素作为参数,以使它们能在其他地方被存储和访问。

分为两种写法

1. 不知道叫什么,有点麻烦的。。。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel">
    const app = document.getElementById('app')

    class Goods extends React.Component {
        myInput2 = null //1. 声明一个存放实例的变量值
        myInputRef = el => { //2. 声明一个方法,将el实例对象赋值给存放实例的变量值
            this.myInput2 = el
        }

        input2Click = () => {
            alert(this.myInput2.value)
        }

        render() {
            const {input2Click} = this
            return (
                <div>
                    <label>
                        <!-- 3.ref绑定将实例对象赋值给存放实例对象的方法 -->
                        <input ref={this.myInputRef} type="text"/>
                    </label>
                    <button onClick={input2Click}>点击我输入框聚焦</button>
                </div>
            );
        }
    }

    ReactDOM.render(<Goods/>, app)
</script>
</body>
</html>

2. 行内的写法,简单点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel">
    const app = document.getElementById('app')

    class Goods extends React.Component {
        inputClick = () => {
            // 2.可直接使用this.myInput获取到当前的实例
            alert(this.myInput.value)
        }

        render() {
            const {inputClick, input2Click} = this
            return (
                <div>
                    <label>
                        <!-- 1. 直接在ref中,进行回调函数,将实例对象赋值给this.myInput -->
                        <input ref={el => this.myInput = el} type="text"/>
                    </label>
                    <button onClick={inputClick}>点击我输入框聚焦</button>
                </div>
            );
        }
    }

    ReactDOM.render(<Goods/>, app)
</script>
</body>
</html>

关于回调 refs 的说明

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

3. 最新的使用 React.createRef()

写法不复杂,目前是react官方极力推荐的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script type="text/babel">
    const app = document.getElementById('app')

    class Goods extends React.Component {
        myInput = React.createRef()  //1.使用React.createRef()创建一个存放实例对象的变量
        inputClick = () => {
            const myInput = this.myInput.current  //3.需要通过current才能访问到此实例对象
            alert(myInput.value)
        }

        render() {
            const {inputClick} = this
            return (
                <div>
                    <label>
                        <!--2.ref中直接绑定this.myInput-->
                        <input ref={this.myInput} type="text"/>
                    </label>
                    <button onClick={inputClick}>点击我输入框聚焦</button>
                </div>
            );
        }
    }

    ReactDOM.render(<Goods/>, app)
</script>
</body>
</html>

需要注意的是,React.createRef()是一对一的,就是说,如果你还想在其他的组件或dom上绑定上ref,那就需要创建多个存放实例对象的变量!

总结

目前公司的挺多项目,应该还是采用的回调形式的ref或者是更老的字符串形式的ref,我的建议是,字符串的ref能不用就不用,虽然它是最简单的。。。至于回调或者是最新的createRef,看当前项目所处的react版本吧!