如何更轻松的对React refs 的理解?都有哪些应用场景?

React refs 的理解与应用

refs 是 React 提供的一种机制,用于直接访问 DOM 元素或 React 组件实例。在 React 中,refs 主要用于获取对 DOM 元素的引用,或访问类组件中的实例方法。在许多情况下,refs 是避免使用传统的 JavaScript 操作 DOM 的一种方式,同时也能解决一些特定场景中的问题,比如:获取输入框的值、管理焦点、动画、或者与第三方库集成。

目录结构:

  1. React refs 的基本概念
  2. refs 的创建方式
  3. 常见的应用场景
    • 3.1 获取 DOM 元素的引用
    • 3.2 管理焦点、文本选择或媒体播放
    • 3.3 集成第三方库
  4. 结合实际项目的代码示例
    • 4.1 获取 DOM 元素并聚焦
    • 4.2 使用 ref 管理组件实例方法
  5. 总结

React refs 的基本概念

refs 是 React 提供的一个 API,允许你获取对 DOM 元素或 React 组件实例的引用。通过 refs,你可以直接操作这些元素或组件,执行例如修改属性、调用方法等操作。它与 React 的声明式 UI 不同,更接近于传统的命令式编程。

refs 的创建方式

在 React 中,可以通过以下方式创建 refs

  1. 使用 React.createRef() (推荐的做法,尤其在类组件中使用):
    React.createRef() 返回一个包含 current 属性的对象,current 属性指向组件的 DOM 元素或实例。

  2. 通过回调函数创建 ref

    在函数组件中,ref 可以通过回调函数来创建。

常见的应用场景

3.1 获取 DOM 元素的引用

最常见的使用场景是直接访问 DOM 元素,例如获取 <input> 元素的值,或者操作一个元素的样式。

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

当你需要在页面加载时或用户操作时自动聚焦一个输入框、播放一个视频,或者控制一个媒体元素时,refs 是非常有用的。

3.3 集成第三方库

在一些与 React 兼容性差的第三方库中,可能需要通过 refs 来获取 DOM 元素的引用并进行直接操作。


结合实际项目的代码示例

4.1 获取 DOM 元素并聚焦

在一个表单中,假设我们有一个文本框,需要在页面加载时将焦点设置到这个文本框上。可以通过 refs 来实现。

jsx 复制代码
import React, { useEffect, useRef } from 'react';

const FocusInput = () => {
  // 使用 useRef 创建 ref
  const inputRef = useRef(null);

  // 使用 useEffect 在组件挂载时聚焦输入框
  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return (
    <div>
      <h3>聚焦输入框示例</h3>
      <input ref={inputRef} type="text" placeholder="请输入内容" />
    </div>
  );
};

export default FocusInput;

解释:

  • useRef 用于创建一个 ref,并将其赋给 <input> 元素。
  • useEffect 中的 inputRef.current.focus() 会在组件加载时将焦点聚焦到输入框。
4.2 使用 ref 管理组件实例方法

refs 也可以用来访问类组件实例,调用组件的实例方法。在函数组件中,我们使用 forwardRefuseImperativeHandle 来暴露组件方法。

假设我们有一个计时器组件,父组件需要控制它的开始和暂停。

jsx 复制代码
// Timer.js
import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react';

const Timer = forwardRef((props, ref) => {
  const [time, setTime] = useState(0);
  const intervalRef = useRef(null);

  // 暴露给父组件的控制方法
  useImperativeHandle(ref, () => ({
    start: () => {
      if (!intervalRef.current) {
        intervalRef.current = setInterval(() => {
          setTime((prevTime) => prevTime + 1);
        }, 1000);
      }
    },
    stop: () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    },
  }));

  useEffect(() => {
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current);
    };
  }, []);

  return <div>计时器: {time} 秒</div>;
});

export default Timer;

// ParentComponent.js
import React, { useRef } from 'react';
import Timer from './Timer';

const ParentComponent = () => {
  const timerRef = useRef(null);

  return (
    <div>
      <h3>父组件控制子组件计时器</h3>
      <button onClick={() => timerRef.current.start()}>开始</button>
      <button onClick={() => timerRef.current.stop()}>停止</button>
      <Timer ref={timerRef} />
    </div>
  );
};

export default ParentComponent;

解释:

  • Timer 组件中,使用 forwardRefuseImperativeHandle 来暴露 startstop 方法,使得父组件可以控制子组件的行为。
  • 父组件通过 timerRef.current.start()timerRef.current.stop() 来调用子组件的计时器控制方法。

总结

React refs 是一种强大的工具,它使得我们可以直接访问 DOM 元素和组件实例。虽然 refs 有时被认为是"不太 React 化"的方式,但在特定场景下,refs 可以大大简化开发,避免过多的状态管理。常见的应用场景包括获取 DOM 元素、管理焦点、文本选择、集成第三方库等。

关键要点:

  • 使用 refs 时要谨慎,因为它打破了 React 的声明式编程范式。
  • refs 适用于那些无法通过状态管理来处理的需求,如焦点控制和与非 React 代码的交互。
相关推荐
随心Coding4 小时前
【零基础入门Go语言】struct 和 interface:Go语言是如何实现继承的?
前端·golang
金州饿霸5 小时前
YARN 架构组件及原理
linux·运维·前端
还这么多错误?!5 小时前
webpack打包要义
前端·webpack
小九九的爸爸5 小时前
浅谈ViewBox那些事(一)
前端·svg
ฅQSω[*邱╭5 小时前
写个自己的vue-cli
前端·javascript·vue.js·学习
阿芯爱编程5 小时前
typescript语法讲解
前端·javascript
Daniel_1876 小时前
Promise-课堂笔记
前端·javascript·笔记
一点一木6 小时前
TensorFlow.js 和 Brain.js 全面对比:哪款 JavaScript AI 库更适合你?
前端·javascript·人工智能