React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > React Ref

React中Ref的作用小结

作者: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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文