React中Ref的作用小结

 更新时间:2024年11月10日 10:36:04   作者:ZL不懂前端  
本文文章介绍了React中的Ref概念,包括其基础概念、使用方式,并讨论了在React中通过Ref操作DOM值时避免组件不更新的问题,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧

一、Ref的基础概念

Ref是React提供的一个接口,允许我们访问在渲染过程中创建的DOM节点或组件实例。它通常用于需要直接操作DOM或访问组件内部状态的情况。值得注意的是,Ref并不属于React的数据流的一部分,因此它的变更不会触发组件的重新渲染。

二、Ref的使用方式

createRef方法

React 16.3引入了createRef方法,它允许我们创建一个可变的Ref对象,并将其赋值给一个类属性。这个Ref对象有一个current属性,该属性指向被引用的DOM节点或组件实例。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myInputRef = React.createRef();
  }
 
  focusInput = () => {
    this.myInputRef.current.focus();
  };
 
  render() {
    return (
      <div>
        <input type="text" ref={this.myInputRef} />
        <button onClick={this.focusInput}>聚焦输入框</button>
      </div>
    );
  }
}

函数组件中的useRef

在函数组件中,由于它们没有实例,因此不能直接使用this.refs来访问Ref。但是,React提供了useRef钩子,它允许我们在函数组件中创建和使用Ref。

import React, { useRef } from 'react';
 
const MyFunctionComponent = () => {
  const inputRef = useRef(null);
 
  const focusInput = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  };
 
  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={focusInput}>聚焦输入框</button>
    </div>
  );
};

回调函数Ref

回调函数Ref是一种更为灵活和推荐的使用方式。通过提供一个回调函数,我们可以在Ref被设置或更新时执行自定义逻辑。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myInputRef = null;
  }
 
  setMyInputRef = (element) => {
    this.myInputRef = element;
  };
 
  focusInput = () => {
    if (this.myInputRef) {
      this.myInputRef.focus();
    }
  };
 
  render() {
    return (
      <div>
        <input type="text" ref={this.setMyInputRef} />
        <button onClick={this.focusInput}>聚焦输入框</button>
      </div>
    );
  }
}

三、ref操作值但组件不更新的问题

在 React 中,组件的更新通常是由状态(state)或属性(props)的变化触发的。当使用ref直接操作组件的值时,React 并不知道这个值已经改变了,因为ref绕过了 React 的响应式更新机制。React 的更新机制是基于虚拟 DOM 的比较,只有当state或props发生变化时,React 才会重新渲染组件。
在函数组件中,我们通常使用React的useState和useRef钩子来管理状态和引用,与类组件类似,直接通过Ref修改状态通常不会触发组件的重新渲染。这是因为Ref主要用于直接访问DOM元素或组件实例,而不是用于管理状态。

举例

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

const SimpleInputComponent = () => {
  const [inputValue, setInputValue] = useState(0); // React状态
  const inputRef = useRef(0); // DOM引用

  // 处理输入框变化,更新React状态
  const handleInputChange = (event) => {
    setInputValue(event.target.value);
  };

  // 直接通过Ref修改DOM值(不推荐)
  const forceUpdateDOMValue = () => {
    if (inputRef.current) {
      inputRef.current.value = 1;
      // 注意:这里虽然DOM值变了,但React状态inputValue没有变
    }
  };

  // 通过useState更新状态(推荐)
  const updateStateValue = () => {
    setInputValue(2);
  };

  return (
    <div>
      <input
        type="text"
        value={inputValue} // 这里绑定的是React状态
        onChange={handleInputChange} // 更改时会更新React状态
        ref={inputRef} // 绑定DOM引用
      />
      <button onClick={forceUpdateDOMValue}>通过Ref直接修改DOM值</button>
      <button onClick={updateStateValue}>通过useState更新状态</button>
      <p>当前React状态值:{inputValue}</p>
    </div>
  );
};

export default SimpleInputComponent;

在这个例子中,我们有一个输入框和两个按钮。当你输入文字时,React状态inputValue会更新,并且组件会重新渲染以反映新的状态。然而,当你点击“通过Ref直接修改DOM值”按钮时,虽然输入框的DOM值被改变了,但React状态inputValue并没有改变,因此页面上显示的React状态值不会更新。相反,当你点击“通过useState更新状态”按钮时,React状态inputValue会被更新,并且组件会重新渲染以显示新的状态值。

到此这篇关于React中Ref的作用小结的文章就介绍到这了,更多相关React Ref内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 从零开始搭建webpack+react开发环境的详细步骤

    从零开始搭建webpack+react开发环境的详细步骤

    这篇文章主要介绍了从零开始搭建webpack+react开发环境的详细步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • React跨端动态化之从JS引擎到RN落地详解

    React跨端动态化之从JS引擎到RN落地详解

    这篇文章主要为大家介绍了React跨端动态化之从JS引擎到RN落地,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Unity RectTransform详解

    Unity RectTransform详解

    unity中的ui元素是有严格的父子关系的,子物体的位置是根据父物体的变化而变化的,而子物体和父物体联系的桥梁就是Anchor,本文重点介绍Unity RectTransform的相关知识,感兴趣的朋友一起看看吧
    2024-01-01
  • react中使用redux-persist做持久化储存的过程记录

    react中使用redux-persist做持久化储存的过程记录

    这篇文章主要介绍了react中使用redux-persist做持久化储存的相关资料,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • React路由的history对象的插件history的使用解读

    React路由的history对象的插件history的使用解读

    这篇文章主要介绍了React路由的history对象的插件history的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • 深入理解React调度(Scheduler)原理

    深入理解React调度(Scheduler)原理

    本文主要介绍了深入理解React调度(Scheduler)原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 解决React报错useNavigate() may be used only in context of Router

    解决React报错useNavigate() may be used only in context of

    这篇文章主要为大家介绍了解决React报错useNavigate() may be used only in context of Router,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • React 使用recharts实现散点地图的示例代码

    React 使用recharts实现散点地图的示例代码

    这篇文章主要介绍了React 使用recharts实现散点地图的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • 详解react使用react-bootstrap当轮子造车

    详解react使用react-bootstrap当轮子造车

    本篇文章主要介绍了详解react使用react-bootstrap当轮子造车,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-08-08
  • React hook实现简单的websocket封装方式

    React hook实现简单的websocket封装方式

    这篇文章主要介绍了React hook实现简单的websocket封装方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论