当前位置: 首页 > article >正文

React 中如何使用ref来访问 DOM 元素或组件实例,有哪些注意事项?

大白话React 中如何使用ref来访问 DOM 元素或组件实例,有哪些注意事项?

在 React 里,ref 就像是一个神奇的小助手,能让你直接去访问 DOM 元素或者组件实例。这就好比你在一群人中,能直接叫出某个人的名字并和他交流一样。接下来,我会详细说说怎么用 ref,还会告诉你使用的时候有哪些要注意的地方。

怎么使用 ref 访问 DOM 元素

1. 使用 createRef 创建 ref
import React, { createRef } from 'react';

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        // 创建一个 ref 对象,用来存储 DOM 元素的引用
        this.myRef = createRef();
    }

    componentDidMount() {
        // 在组件挂载完成后,通过 ref 对象访问 DOM 元素
        // 这里可以对这个 DOM 元素进行各种操作,比如修改样式
        this.myRef.current.style.color = 'red';
    }

    render() {
        return (
            // 将 ref 对象绑定到一个 DOM 元素上
            <div ref={this.myRef}>
                这是一个使用 ref 访问的 DOM 元素
            </div>
        );
    }
}

export default MyComponent;

在上面的代码里,我们首先用 createRef 创建了一个 ref 对象 this.myRef。然后在 render 方法里,把这个 ref 对象绑定到了一个 <div> 元素上。当组件挂载完成后,在 componentDidMount 方法里,我们就可以通过 this.myRef.current 来访问这个 <div> 元素,并且对它进行样式修改。

2. 使用 useRef Hook(函数组件)
import React, { useRef } from 'react';

const MyFunctionComponent = () => {
    // 使用 useRef 创建一个 ref 对象
    const myRef = useRef(null);

    const handleClick = () => {
        // 点击按钮时,通过 ref 对象访问 DOM 元素并修改它的文本内容
        myRef.current.textContent = '文本内容已修改';
    };

    return (
        <div>
            {/* 将 ref 对象绑定到一个 DOM 元素上 */}
            <p ref={myRef}>这是一个使用 ref 访问的 DOM 元素</p>
            <button onClick={handleClick}>点击修改文本</button>
        </div>
    );
};

export default MyFunctionComponent;

在函数组件里,我们用 useRef 来创建 ref 对象。然后把这个 ref 对象绑定到一个 <p> 元素上。当点击按钮时,通过 myRef.current 访问这个 <p> 元素并修改它的文本内容。

怎么使用 ref 访问组件实例

类组件
import React, { createRef } from 'react';

// 定义一个子组件
class ChildComponent extends React.Component {
    showMessage() {
        // 子组件的方法,用于显示消息
        alert('这是子组件的消息');
    }

    render() {
        return <div>子组件</div>;
    }
}

class ParentComponent extends React.Component {
    constructor(props) {
        super(props);
        // 创建一个 ref 对象,用来存储子组件实例的引用
        this.childRef = createRef();
    }

    handleClick = () => {
        // 点击按钮时,通过 ref 对象访问子组件实例并调用它的方法
        this.childRef.current.showMessage();
    };

    render() {
        return (
            <div>
                {/* 将 ref 对象绑定到子组件上 */}
                <ChildComponent ref={this.childRef} />
                <button onClick={this.handleClick}>点击调用子组件方法</button>
            </div>
        );
    }
}

export default ParentComponent;

在这个例子中,我们定义了一个子组件 ChildComponent,它有一个 showMessage 方法。在父组件 ParentComponent 里,我们创建了一个 ref 对象 this.childRef,并把它绑定到子组件上。当点击按钮时,通过 this.childRef.current 访问子组件实例并调用它的 showMessage 方法。

使用 ref 的注意事项

  1. ref 在组件挂载完成后才可用:在 componentDidMount 或者 useEffect 里使用 ref 是比较安全的,因为这时组件已经挂载完成,ref 对象的 current 属性才会指向实际的 DOM 元素或者组件实例。
  2. 不要在 render 方法里修改 ref 指向的元素或实例render 方法是用来描述 UI 的,不应该在里面进行副作用操作,比如修改 DOM 元素的属性。修改操作应该放在生命周期方法或者 useEffect 里。
  3. 函数组件默认不支持 ref:如果要在函数组件里使用 ref,可以使用 forwardRef 来转发 ref。例如:
import React, { forwardRef } from 'react';

const MyFunctionComponentWithRef = forwardRef((props, ref) => {
    return <div ref={ref}>这是一个支持 ref 的函数组件</div>;
});

export default MyFunctionComponentWithRef;

这样,就可以把 ref 传递给函数组件了。

通过上面的介绍,你应该对 React 里怎么使用 ref 有了更清楚的认识,同时也知道了使用时的注意事项。希望这些内容能帮助你更好地使用 React 开发项目!

除了createRef,React中还有哪些方法可以创建ref?

在 React 里,除了 createRef 之外,还有其他方法能创建 ref,下面为你详细介绍:

1. 回调 ref

回调 ref 是通过给 ref 属性传入一个函数来创建的。这个函数会在组件挂载或卸载时被调用。在组件挂载时,函数会接收 DOM 元素或组件实例作为参数;在组件卸载时,函数会接收 null 作为参数。

下面是一个使用回调 ref 的示例:

import React from 'react';

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        // 初始化一个属性来存储 ref
        this.myRef = null;
        // 定义一个回调函数,用于接收 ref
        this.setMyRef = (element) => {
            this.myRef = element;
            if (this.myRef) {
                // 当 ref 可用时,可以对元素进行操作
                this.myRef.style.color = 'blue';
            }
        };
    }

    render() {
        return (
            // 使用回调函数作为 ref 属性
            <div ref={this.setMyRef}>
                这是使用回调 ref 访问的 DOM 元素
            </div>
        );
    }
}

export default MyComponent;

在上述代码中,this.setMyRef 是一个回调函数,当 <div> 元素挂载时,该函数会接收这个 <div> 元素作为参数,并将其赋值给 this.myRef。之后,就可以通过 this.myRef 来访问这个 DOM 元素了。

2. useRef Hook(用于函数组件)

useRef 是 React 为函数组件提供的一个 Hook,它可以用来创建一个可变的 ref 对象。这个对象在组件的整个生命周期内保持不变。

下面是一个使用 useRef 的示例:

import React, { useRef } from 'react';

const MyFunctionComponent = () => {
    // 使用 useRef 创建一个 ref 对象
    const myRef = useRef(null);

    const handleClick = () => {
        if (myRef.current) {
            // 点击按钮时,通过 ref 对象访问 DOM 元素并修改它的文本内容
            myRef.current.textContent = '文本内容已更新';
        }
    };

    return (
        <div>
            {/* 将 ref 对象绑定到一个 DOM 元素上 */}
            <p ref={myRef}>这是使用 useRef 访问的 DOM 元素</p>
            <button onClick={handleClick}>点击更新文本</button>
        </div>
    );
};

export default MyFunctionComponent;

在这个函数组件中,useRef 创建了一个 ref 对象 myRef。当点击按钮时,通过 myRef.current 访问 <p> 元素并修改其文本内容。

3. forwardRef 结合 useImperativeHandle(用于函数组件转发 ref

forwardRef 允许函数组件接收 ref 并将其转发给子元素,而 useImperativeHandle 可以自定义暴露给父组件的 ref 实例值。

下面是一个使用 forwardRefuseImperativeHandle 的示例:

import React, { forwardRef, useRef, useImperativeHandle } from 'react';

// 使用 forwardRef 转发 ref
const ChildComponent = forwardRef((props, ref) => {
    const inputRef = useRef();
    // 使用 useImperativeHandle 自定义暴露给父组件的 ref 实例值
    useImperativeHandle(ref, () => ({
        focusInput: () => {
            inputRef.current.focus();
        }
    }));

    return <input ref={inputRef} type="text" />;
});

const ParentComponent = () => {
    const childRef = useRef();

    const handleClick = () => {
        // 调用子组件暴露的方法
        childRef.current.focusInput();
    };

    return (
        <div>
            <ChildComponent ref={childRef} />
            <button onClick={handleClick}>聚焦输入框</button>
        </div>
    );
};

export default ParentComponent;

在这个例子中,ChildComponent 是一个函数组件,通过 forwardRef 接收 ref 并转发给 <input> 元素。useImperativeHandle 自定义了暴露给父组件的 ref 实例值,这里暴露了一个 focusInput 方法。在 ParentComponent 中,通过 childRef 调用子组件暴露的 focusInput 方法,实现聚焦输入框的功能。

在React中,如何使用ref来操作DOM元素的属性和方法?

在 React 里,借助 ref 能够直接操作 DOM 元素的属性与方法。下面会结合不同类型的组件(类组件和函数组件),为你详细阐述使用 ref 操作 DOM 元素属性和方法的具体方式。

类组件中使用 createRef

createRef 是类组件创建 ref 的常用手段。下面是一个示例,展示了怎样使用 createRef 来操作 DOM 元素的属性和方法:

import React, { createRef } from 'react';

class MyClassComponent extends React.Component {
    constructor(props) {
        super(props);
        // 创建一个 ref 对象
        this.myRef = createRef();
    }

    componentDidMount() {
        // 在组件挂载完成后,操作 DOM 元素的属性和方法
        // 修改元素的文本内容
        this.myRef.current.textContent = '文本内容已更新';
        // 修改元素的样式属性
        this.myRef.current.style.color = 'red';
        // 调用元素的方法,这里让元素获得焦点
        this.myRef.current.focus();
    }

    render() {
        return (
            // 将 ref 对象绑定到 input 元素上
            <input type="text" ref={this.myRef} />
        );
    }
}

export default MyClassComponent;    

在上述代码中,先在 constructor 里运用 createRef 创建了 this.myRef。接着在 render 方法中,把 this.myRef 绑定到 <input> 元素上。当组件挂载完成后,在 componentDidMount 方法里,借助 this.myRef.current 操作 <input> 元素的属性(如 textContentstyle.color)和方法(如 focus)。

函数组件中使用 useRef

useRef 是函数组件创建 ref 的主要方式。以下示例展示了如何在函数组件里使用 useRef 操作 DOM 元素的属性和方法:

import React, { useRef, useEffect } from 'react';

const MyFunctionComponent = () => {
    // 使用 useRef 创建一个 ref 对象
    const myRef = useRef(null);

    useEffect(() => {
        // 在组件挂载完成后,操作 DOM 元素的属性和方法
        // 修改元素的文本内容
        myRef.current.textContent = '文本内容已更新';
        // 修改元素的样式属性
        myRef.current.style.color = 'blue';
        // 调用元素的方法,这里让元素获得焦点
        myRef.current.focus();
    }, []);

    return (
        // 将 ref 对象绑定到 input 元素上
        <input type="text" ref={myRef} />
    );
};

export default MyFunctionComponent;    

在这个函数组件中,使用 useRef 创建了 myRef。然后在 useEffect 钩子中,当组件挂载完成后,通过 myRef.current 操作 <input> 元素的属性和方法。

注意事项

  • ref 在组件挂载后才可用:要确保在组件挂载完成后再操作 ref,因为只有在组件挂载后,refcurrent 属性才会指向实际的 DOM 元素。
  • 避免在 render 方法中修改 refrender 方法应当是纯函数,不适合进行副作用操作,如修改 DOM 元素的属性。副作用操作建议放在 componentDidMountuseEffect 中。

在React中,ref和refs的原理及区别

在 React 里,refrefs 在用途和原理上存在明显差异,下面为你详细介绍:

ref 的原理与使用

原理

ref 是 React 提供的一种机制,用于获取 DOM 元素或者组件实例的引用。借助 ref,可以直接操作 DOM 元素,像修改样式、获取元素尺寸,或者调用组件实例的方法。在 React 中,ref 本质上是一个对象,在组件挂载时,ref 对象的 current 属性会指向对应的 DOM 元素或者组件实例;组件卸载时,current 属性会被设置为 null

使用方式
  • 类组件使用 createRef
import React, { createRef } from 'react';

class MyClassComponent extends React.Component {
    constructor(props) {
        super(props);
        // 创建一个 ref 对象
        this.myRef = createRef();
    }

    componentDidMount() {
        // 在组件挂载后,通过 ref 对象的 current 属性访问 DOM 元素
        if (this.myRef.current) {
            this.myRef.current.style.color = 'red';
        }
    }

    render() {
        return (
            // 将 ref 对象绑定到 DOM 元素上
            <div ref={this.myRef}>
                这是使用 createRef 创建的 ref
            </div>
        );
    }
}

export default MyClassComponent;
  • 函数组件使用 useRef
import React, { useRef } from 'react';

const MyFunctionComponent = () => {
    // 使用 useRef 创建一个 ref 对象
    const myRef = useRef(null);

    const handleClick = () => {
        if (myRef.current) {
            // 通过 ref 对象的 current 属性访问 DOM 元素
            myRef.current.textContent = '内容已更新';
        }
    };

    return (
        <div>
            <p ref={myRef}>这是使用 useRef 创建的 ref</p>
            <button onClick={handleClick}>点击更新内容</button>
        </div>
    );
};

export default MyFunctionComponent;

refs 的原理与使用(旧版本)

原理

在 React 旧版本里,refs 是一个对象,可用于存储多个 ref。一般会使用字符串形式的 ref 来创建 refs 对象,不过这种方式现已不推荐使用,因为它存在一些问题,比如不利于代码优化、难以进行静态分析等。

使用方式
import React from 'react';

class OldStyleComponent extends React.Component {
    handleClick = () => {
        // 通过 refs 对象访问 DOM 元素
        if (this.refs.myElement) {
            this.refs.myElement.style.color = 'blue';
        }
    };

    render() {
        return (
            <div>
                {/* 使用字符串形式的 ref */}
                <div ref="myElement">这是使用旧版本 refs 的元素</div>
                <button onClick={this.handleClick}>点击改变颜色</button>
            </div>
        );
    }
}

export default OldStyleComponent;

两者的区别

  • 使用方式
    • ref 既可以用 createRef(类组件)或者 useRef(函数组件)来创建,也可以使用回调 ref;而旧版本的 refs 是通过字符串形式的 ref 来创建的。
  • 兼容性与推荐度
    • ref 是 React 官方推荐的方式,兼容所有 React 版本,并且在代码优化和静态分析方面表现更好;refs(字符串形式的 ref)是旧版本的用法,现已不推荐使用,在 React 16.3 及以后版本中,若使用字符串形式的 ref,控制台会给出警告信息。
  • 功能特性
    • ref 可以使用 forwardRefuseImperativeHandle 来实现 ref 的转发和自定义暴露;refs(字符串形式的 ref)没有这些功能。

综上所述,在新的 React 项目中,建议使用 ref 而不是旧版本的 refs


http://www.kler.cn/a/612084.html

相关文章:

  • Cudann 11.8同时安装tensorflow, pytorch
  • Kafka 的延迟队列、死信队列和重试队列
  • Android设计模式之观察者模式
  • Android 项目缓存问题,某些依赖中的类会报错:Cannot resolve symbol
  • 若依专题——基础应用篇
  • Scala简介与基础
  • 远程办公新体验:用触屏手机流畅操作电脑桌面
  • SpringBoot动态配置数据源的几种实现方式
  • Spring事务与数据库事务的关系
  • 常见邮件协议
  • Oracle Database In-Memory 23ai 新特性
  • 【C++接入大模型】WinHTTP类封装:实现对话式大模型接口访问
  • 适合DBA的brew上手指南
  • (C语言)网络编程之TCP(含三次握手和四次挥手详解)
  • 适配器模式及其典型应用
  • Vue-create-vue-开发流程-项目结构-API风格-ElementPlus-入门准备工作
  • 【保姆级别教程】VMware虚拟机安装Mac OS15苹果系统附带【VMware TooLS安装】【解锁虚拟机】和【Mac OS与真机共享文件夹】手把手教程
  • 分布式共识算法解密:从Paxos到Raft的演进之路
  • 使用string和string_view(一)——C风格字符串、字符串字面量和std::string
  • 批量将 PDF 转换为 Word/PPT/Txt/Jpg图片等其它格式