笔记十四、React中refs的使用

ref:组件中的标签可以通过定义ref属性来标识自己

14.1 字符串形式的ref

代码 App.jsx

import React from "react";

class App extends React.Component {

    // 字符串形式的ref尽量不用,已经弃用,有效率问题
    // 字符串形式的ref尽量不用,已经弃用,有效率问题
    // 字符串形式的ref尽量不用,已经弃用,有效率问题
    popClick = () => {
        // console.log(document.getElementsByTagName("input")[0].value);
        const {inputRef} = this.refs;
        alert(inputRef.value)
    }

    render() {
        return (
            <>
                <input type="text" placeholder="请输入内容" ref={"inputRef"}/>
                <button onClick={this.popClick}>点击获取input内容</button>
            </>
        )
    }
}

export default App

存在效率的问题,已经被弃用

14.2 回调形式的ref (推荐)

何时使用Refs?

管理焦点,文本选择或媒体播放

触发强制动画

集成第三方DOM库

避免使用refs来做任何可以通过声明式实现来完成的事情,不要过度使用refs。

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

14.2.1 (推荐)* 增加点击事件,验证内联方式定义的ref在组件更新的时候会执行两次

代码 

import React from "react";

class App extends React.Component {

    state = {jack: true};

    // 回调形式的ref
    popClick = () => {
        // console.log(document.getElementsByTagName("input")[0].value);
        // const {inputRef} = this.refs;
        alert(this.inputRef.value)
    }

    // 增加点击事件,验证内联方式定义的ref在组件更新的时候会执行两次
    handleClick = () => {
        this.setState({jack: !this.state.jack})
    }

    // 此处 refs是通过内联函数方式定义的
    render() {
        return (
            <>
                <input type="text" placeholder="请输入内容" ref={(e) => (this.inputRef = e, console.log("ref执行了"))}/>
                <button onClick={this.popClick}>点击获取input内容</button>
                <button onClick={this.handleClick}>点击更新组件</button>
            </>
        )
    }
}

export default App

运行结果(点击两次更新组件按钮)

14.2.2 将ref不内联,抽离出来(最常用)* class

将ref定义成class的绑定函数,不会因为更新组件带来重新执行的问题 

代码

import React from "react";

class App extends React.Component {

    state = {jack: true};

    // 回调形式的ref
    popClick = () => {
        // console.log(document.getElementsByTagName("input")[0].value);
        // const {inputRef} = this.refs;
        alert(this.inputRef.value)
    }

    // 增加点击事件,验证内联方式定义的ref在组件更新的时候会执行两次
    handleClick = () => {
        this.setState({jack: !this.state.jack})
    }

    // 将ref定义成class的绑定函数,不会因为更新组件带来重新执行的问题
    refFun = (e) => (this.inputRef = e, console.log("ref执行了"));

    // 此处 refs是通过内联函数方式定义的
    render() {
        return (
            <>
                <input type="text" placeholder="请输入内容" ref={this.refFun}/>
                <button onClick={this.popClick}>点击获取input内容</button>
                <button onClick={this.handleClick}>点击更新组件</button>
            </>
        )
    }
}

export default App

按更新组件按钮三次,结果(首次进入页面,ref执行一次正常)

14.3 createRef创建ref

  • createRef

    • Refs 是使用 React.createRef() 创建的,并通过 ref 属性附加到 React 元素。在构造组件时,通常将 Refs 分配给实例属性,以便可以在整个组件中引用它们
    • React.createRef() 调用后可以想象成创建了一个容器,这个容器可以储存被ref标识的元素节点
    • 创建了一个容器只能绑定一个节点,绑定多个节点会被覆盖

 代码

import React from "react";

class App extends React.Component {

    // 一个容器只能绑定一个节点
    inputRef1 = React.createRef();
    inputRef2 = React.createRef();

    popClick = () => {
        // console.log(this.inputRef.current.value);
        alert(this.inputRef1.current.value)
        alert(this.inputRef2.current.value)
    }

    // 此处 refs是通过内联函数方式定义的
    render() {
        return (
            <>
                <input type="text" placeholder="请输入内容" ref={this.inputRef1}/>
                <input type="text" placeholder="请输入内容" ref={this.inputRef2}/>
                <button onClick={this.popClick}>点击获取input内容</button>
            </>
        )
    }
}

export default App
  • 不要过度使用ref

 当获取input内容和按钮分开时,就需要用ref,但是没有button的话,可以直接使用失焦方法调用

import React from "react";

class App extends React.Component {

    // 一个容器只能绑定一个节点
    inputRef1 = React.createRef();
    inputRef2 = React.createRef();

    popClick = () => {
        // console.log(this.inputRef.current.value);
        alert(this.inputRef1.current.value)
        alert(this.inputRef2.current.value)
    }

    // input 失焦事件触发 可以替代ref
    // input 失焦事件触发 可以替代ref
    // input 失焦事件触发 可以替代ref
    // input 失焦事件触发 可以替代ref
    blur = (e) => {
        console.log(e.target.value);
    }

    // 此处 refs是通过内联函数方式定义的
    render() {
        return (
            <>
                <input type="text" placeholder="请输入内容" ref={this.inputRef1}/>
                <input type="text" placeholder="请输入内容" ref={this.inputRef2}/>
                <button onClick={this.popClick}>点击获取input内容</button>
                <input type="text" onBlur={this.blur}/>
            </>
        )
    }
}

export default App

React 结合 TypeScript 使用 Refs 可以通过 `React.RefObject` 接口来定义 Ref 类型,具体步骤如下: 1. 首先,在组件定义一个 Ref 对象: ```typescript import React, { useRef } from 'react'; interface MyComponentProps { // props } const MyComponent: React.FC<MyComponentProps> = (props) => { const inputRef = useRef<HTMLInputElement>(null); // ... }; ``` 这里我们定义了一个名为 `inputRef` 的 Ref 对象,它的类型是 `React.RefObject<HTMLInputElement>`,指向一个 input 元素。 2. 将 Ref 对象传递给组件的元素或组件: ```typescript return ( <div> <input type="text" ref={inputRef} /> </div> ); ``` 这里我们将 `inputRef` 传递给了 input 元素的 `ref` 属性,这样在组件渲染完毕后,我们就可以通过 `inputRef.current` 来访问这个 input 元素了。 3. 在组件使用 Ref 对象: ```typescript const handleClick = () => { if (inputRef.current) { inputRef.current.focus(); } } return ( <div> <input type="text" ref={inputRef} /> <button onClick={handleClick}>Focus</button> </div> ); ``` 这里我们定义了一个 `handleClick` 方法,当用户点击按钮时,调用这个方法,它会将焦点聚焦到 input 元素上。通过 `inputRef.current` 可以获取当前 input 元素的引用,然后调用 `focus()` 方法即可聚焦。 以上就是在 React 结合 TypeScript 使用 Refs 的基本步骤。需要注意的是,当使用 Refs 时,要确保对 Ref 对象的访问是安全的,即先检查 `ref.current` 是否为 null,然后再进行操作,以避免出现运行时错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ElendaLee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值