Skip to content
📈0️⃣

React 中 Refs

React 中的 Refs 主要用于获取 DOM 节点或 React 元素实例,并允许用户直接访问和操作这些对象。

Refs 的用途

以下是 Refs 的一些常见用途:

  • 管理焦点、文本选择或媒体播放:当需要在组件中处理用户的交互,如输入框的聚焦、文本的选择或者视频的播放控制时,可以使用 Refs 来直接操作 DOM。
  • 触发强制动画:在某些情况下,可能需要对组件进行精确控制的动画,这时可以通过 Refs 来访问和修改组件的状态。
  • 集成第三方 DOM 库:当需要将 React 应用与某些第三方 DOM 操作库结合使用时,Refs 提供了一种方式来将 React 组件与这些库集成。

需要注意的是,虽然 Refs 提供了直接操作 DOM 的能力,但 React 官方建议避免过度使用 Refs,尤其是在可以通过状态(state)和属性(props)来实现的情况下。因为过度使用 Refs 可能会破坏 React 的单向数据流原则,使得代码难以维护和理解。

使用方法

在使用 Refs 时,通常有两种方式:

  • 字符串 Refs:这是早期的方式,通过字符串形式的 ref 属性来设置,但这种方式在多个元素上使用时会变得不够灵活。
  • 回调 Refs:这是推荐的方式,通过一个回调函数来接收对应的 DOM 节点或 React 元素实例的引用。这种方式更加灵活,可以在不同的生命周期阶段获取到最新的引用。
  • useRef():useRef 钩子是用于创建 ref 的另一种方法。与类组件中的 createRef 方法不同,useRef 为函数组件提供了一种访问 DOM 节点或其他 React 元素的能力,而无需使用 this 关键字或类。

使用方法如下:

案例: 1. 类组件 - 字符串实现

通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用。以下是一个实例:

javascript
// 案例: 1. 类组件 - 字符串实现
class MyComponent extends React.Component {
  handleClick() {
    this.refs.myInput.focus();
  }
  render() {
    // 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
    return (
      <div>
        <input type="text" ref="myInput" />
        <input
          type="button"
          value="点我输入框获取焦点"
          onClick={this.handleClick.bind(this)}
        />
      </div>
    );
  }
}
ReactDOM.render(<MyComponent />, document.getElementById("app1"));

案例: 2. 类组件 - 回调实现

js
// 案例: 2. 类组件 - 回调实现
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }
  handleClick() {
    this.inputRef.current.focus();
  }
  render() {
    return (
      <div>
        <input type="text" ref={this.inputRef} />
        <input
          type="button"
          value="点我输入框获取焦点"
          onClick={this.handleClick.bind(this)}
        />
      </div>
    );
  }
}
ReactDOM.render(<MyComponent />, document.getElementById("app2"));

案例: 3. 函数组件 - useRef 实现

通过 useRef,你可以像在类组件中一样操作和访问 DOM 节点,但更加简洁,并且不需要引入类组件的复杂性。

useRef 用法

  1. 初始化 ref: useRef 返回一个可变的 ref 对象,该对象在组件的整个生命周期内保持不变。useRef 接受一个可选的初始化值作为参数。

  2. 读取 ref: 使用 ref.current 属性来访问 ref 对象关联的当前 DOM 节点或 React 组件实例。

  3. 更新 ref: 可以通过 ref.current 赋值来更新 ref 对象关联的值。

js
// 案例: 3. 函数组件 - useRef实现
const MyComponent = function () {
  const inputRef = React.useRef(null);
  const handleClick = () => {
    inputRef.current.focus();
  };
  return (
    <div>
      <input type="text" ref={inputRef} />
      <input type="button" value="点我输入框获取焦点" onClick={handleClick} />
    </div>
  );
};
ReactDOM.render(<MyComponent />, document.getElementById("app3"));

代码与演示

1. 全部代码

点击查看代码
html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>test-react-jsx</title>
    <!-- <script src="https://cdn.staticfile.org/react/18.0.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/18.0.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script> -->
    <script src="./react.js"></script>
    <script src="./react-dom.js"></script>
    <script src="./babel.js"></script>
  </head>

  <body>
    <div id="app1"></div>
    <div id="app2"></div>
    <div id="app3"></div>

    <script type="text/babel">
      (function () {
        // 案例: 1. 类组件 - 字符串实现
        class MyComponent extends React.Component {
          handleClick() {
            this.refs.myInput.focus();
          }
          render() {
            // 当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
            return (
              <div>
                <input type="text" ref="myInput" />
                <input
                  type="button"
                  value="点我输入框获取焦点"
                  onClick={this.handleClick.bind(this)}
                />
              </div>
            );
          }
        }
        ReactDOM.render(<MyComponent />, document.getElementById("app1"));
      })();
    </script>

    <script type="text/babel">
      (function () {
        // 案例: 2. 类组件 - 回调实现
        class MyComponent extends React.Component {
          constructor(props) {
            super(props);
            this.inputRef = React.createRef();
          }
          handleClick() {
            this.inputRef.current.focus();
          }
          render() {
            return (
              <div>
                <input type="text" ref={this.inputRef} />
                <input
                  type="button"
                  value="点我输入框获取焦点"
                  onClick={this.handleClick.bind(this)}
                />
              </div>
            );
          }
        }
        ReactDOM.render(<MyComponent />, document.getElementById("app2"));
      })();
    </script>

    <script type="text/babel">
      (function () {
        // 案例: 3. 函数组件 - useRef实现
        const MyComponent = function () {
          const inputRef = React.useRef(null);
          const handleClick = () => {
            inputRef.current.focus();
          };
          return (
            <div>
              <input type="text" ref={inputRef} />
              <input
                type="button"
                value="点我输入框获取焦点"
                onClick={handleClick}
              />
            </div>
          );
        };
        ReactDOM.render(<MyComponent />, document.getElementById("app3"));
      })();
    </script>
  </body>
</html>

2. 案例演示




test-react-refs.html 资源加载中...