React Refs 完整使用指南

React Refs 完整使用指南

1. Refs 基础用法

1.1 创建和访问 Refs

// 类组件中使用 createRef
class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  componentDidMount() {
    // 访问 DOM 节点
    console.log(this.myRef.current);
  }

  render() {
    return <div ref={this.myRef}>Hello</div>;
  }
}

// 函数组件中使用 useRef
function MyFunctionComponent() {
  const myRef = useRef(null);

  useEffect(() => {
    // 访问 DOM 节点
    console.log(myRef.current);
  }, []);

  return <div ref={myRef}>Hello</div>;
}

1.2 回调 Refs

class CallbackRefComponent extends React.Component {
  setTextInputRef = (element) => {
    this.textInput = element;
  };

  focusTextInput = () => {
    // 直接使用原生 DOM API
    if (this.textInput) this.textInput.focus();
  };

  render() {
    return (
      <>
        <input type="text" ref={this.setTextInputRef} />
        <button onClick={this.focusTextInput}>
          Focus the text input
        </button>
      </>
    );
  }
}

2. Refs 常见用途

2.1 管理焦点

function FocusInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    // 组件挂载时自动聚焦
    inputRef.current.focus();
  }, []);

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={() => inputRef.current.focus()}>
        Focus Input
      </button>
    </div>
  );
}

2.2 文本选择

function TextSelection() {
  const textRef = useRef(null);

  const selectText = () => {
    if (textRef.current) {
      textRef.current.select();
    }
  };

  return (
    <div>
      <input
        ref={textRef}
        type="text"
        defaultValue="Click to select me"
      />
      <button onClick={selectText}>Select Text</button>
    </div>
  );
}

2.3 媒体控制

function VideoPlayer() {
  const videoRef = useRef(null);

  const handlePlay = () => {
    videoRef.current.play();
  };

  const handlePause = () => {
    videoRef.current.pause();
  };

  return (
    <div>
      <video ref={videoRef}>
        <source src="video.mp4" type="video/mp4" />
      </video>
      <button onClick={handlePlay}>Play</button>
      <button onClick={handlePause}>Pause</button>
    </div>
  );
}

3. Refs 转发

3.1 基本 Ref 转发

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="fancy-button">
    {props.children}
  </button>
));

// 使用转发的 ref
function Parent() {
  const buttonRef = useRef(null);

  useEffect(() => {
    console.log(buttonRef.current); // 访问 button DOM 节点
  }, []);

  return <FancyButton ref={buttonRef}>Click me!</FancyButton>;
}

3.2 高阶组件中的 Ref 转发

function withLogger(WrappedComponent) {
  class LoggerComponent extends React.Component {
    componentDidUpdate(prevProps) {
      console.log('Props updated', prevProps, this.props);
    }

    render() {
      const {forwardedRef, ...rest} = this.props;
      return <WrappedComponent ref={forwardedRef} {...rest} />;
    }
  }

  return React.forwardRef((props, ref) => {
    return <LoggerComponent {...props} forwardedRef={ref} />;
  });
}

// 使用高阶组件
const ButtonWithLogger = withLogger(FancyButton);

4. Refs 与函数组件

4.1 useImperativeHandle 使用

const FancyInput = React.forwardRef((props, ref) => {
  const inputRef = useRef(null);

  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
    getValue: () => {
      return inputRef.current.value;
    },
    setValue: (value) => {
      inputRef.current.value = value;
    }
  }));

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

// 使用自定义 ref 方法
function Parent() {
  const inputRef = useRef(null);

  const handleClick = () => {
    inputRef.current.focus();
    inputRef.current.setValue('Hello!');
    console.log(inputRef.current.getValue());
  };

  return (
    <div>
      <FancyInput ref={inputRef} />
      <button onClick={handleClick}>Manipulate Input</button>
    </div>
  );
}

5. Refs 的高级用法

5.1 多个 Refs 管理

function MultipleRefs() {
  const refs = useRef({});

  const setRef = (id) => (element) => {
    refs.current[id] = element;
  };

  const focusRandom = () => {
    const keys = Object.keys(refs.current);
    const randomKey = keys[Math.floor(Math.random() * keys.length)];
    refs.current[randomKey]?.focus();
  };

  return (
    <div>
      <input ref={setRef('input1')} placeholder="Input 1" />
      <input ref={setRef('input2')} placeholder="Input 2" />
      <input ref={setRef('input3')} placeholder="Input 3" />
      <button onClick={focusRandom}>Focus Random Input</button>
    </div>
  );
}

5.2 条件性 Refs

function ConditionalRef() {
  const [showInput, setShowInput] = useState(true);
  const inputRef = useRef(null);

  useEffect(() => {
    if (showInput) {
      inputRef.current?.focus();
    }
  }, [showInput]);

  return (
    <div>
      <button onClick={() => setShowInput(!showInput)}>
        Toggle Input
      </button>
      {showInput && <input ref={inputRef} />}
    </div>
  );
}

6. Refs 最佳实践

6.1 避免过度使用

// 不推荐
function BadExample() {
  const divRef = useRef(null);

  const updateContent = () => {
    // 不推荐直接操作 DOM
    divRef.current.innerHTML = 'Updated content';
  };

  return <div ref={divRef}>Content</div>;
}

// 推荐
function GoodExample() {
  const [content, setContent] = useState('Content');

  return <div>{content}</div>;
}

6.2 清理 Refs

function CleanupExample() {
  const timerRef = useRef(null);

  useEffect(() => {
    timerRef.current = setInterval(() => {
      console.log('Tick');
    }, 1000);

    // 清理定时器
    return () => {
      clearInterval(timerRef.current);
    };
  }, []);

  return <div>Timer Example</div>;
}

7. 总结

Refs 使用要���:

  1. 适用场景:

    • DOM 元素的直接操作
    • 媒体播放控制
    • 文本选择和焦点管理
    • 第三方 DOM 库的集成
  2. 注意事项:

    • 避免过度使用 Refs
    • 优先使用声明式编程
    • 及时清理 Refs 资源
    • 谨慎使用 Refs 操作 DOM
  3. 性能考虑:

    • Refs 更新不会触发重新渲染
    • 适当使用可以避免不必要的渲染
    • 大量 Refs 可能影响内存使用
  4. 开发建议:

    • 优先使用 React 的声明式 API
    • 只在必要时使用 Refs
    • 使用 TypeScript 增加类型安全
    • 保持代码的可维护性
      </rewritten_file>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/943375.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLO11改进-注意力-引入自调制特征聚合模块SMFA

本篇文章将介绍一个新的改进机制——SMFA&#xff08;自调制特征聚合模块&#xff09;&#xff0c;并阐述如何将其应用于YOLOv11中&#xff0c;显著提升模型性能。随着深度学习在计算机视觉中的不断进展&#xff0c;目标检测任务也在快速发展。YOLO系列模型&#xff08;You Onl…

js-000000000000

1、js书写的位置 - 内部 <body> <!-- 习惯把 js 放到 /body 的后面 --> <script> console.log(这是内部 js 的书写位置) alert(内部js) </script> </body> <body><!-- 习惯把 js 放到 /body 的后面 --><script>console.log(这…

Android笔记(四十):ViewPager2嵌套RecyclerView滑动冲突进一步解决

背景 ViewPager2内嵌套横向滑动的RecyclerView&#xff0c;会有滑动冲突的情况&#xff0c;引入官方提供的NestedScrollableHost类可以解决冲突问题&#xff0c;但是有一些瑕疵&#xff0c;滑动横向RecyclerView到顶部&#xff0c;按住它不放手继续往左拖再往右拖&#xff0c;这…

Taro小程序开发性能优化实践

我们团队在利用Taro进行秒送频道小程序的同时&#xff0c;一直在探索性能优化的最佳实践。随着需求的不断迭代&#xff0c;项目中的性能问题难免日积月累&#xff0c;逐渐暴露出来影响用户体验。适逢双十一大促&#xff0c;我们趁着这个机会统一进行了Taro性能优化实践&#xf…

jangow-01-1.0.1靶机

靶机 ip&#xff1a;192.168.152.155 把靶机的网络模式调成和攻击机kali一样的网络模式&#xff0c;我的kali是NAT模式, 在系统启动时(长按shift键)直到显示以下界面 ,我们选第二个&#xff0c;按回车。 继续选择第二个&#xff0c;这次按 e 进入编辑页面 接下来&#xff0c;…

03.HTTPS的实现原理-HTTPS的工作流程

03.HTTPS的实现原理-HTTPS的工作流程 简介1. HTTPS的工作流程1.1. TCP的工作流程1.1.1. 三次握手的详细步骤1.1.2. 三次握手的作用 1.2. HTTPS的工作流程1.2.1. HTTPS与TCP的关系1.2.2. HTTPS的工作流程 2. 公钥和私钥的作用3. 对称密钥的生成和交换4. 对称加密和非对称加密的区…

阿里云人工智能ACA(五)——深度学习基础

一、深度学习概述 1. 深度学习概念 1-1. 深度学习基本概念 深度学习是机器学习的一个分支基于人工神经网络&#xff08;模仿人脑结构&#xff09;通过多层网络自动学习特征能够处理复杂的模式识别问题 1-2. 深度学习的优点与缺点 优点 强大的特征学习能力可以处理复杂问题…

MySQL和HBase的对比

Mysql &#xff1a;关系型数据库&#xff0c;主要面向 OLTP &#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持 sql &#xff0c;支持主从、 Group Replication 架构模型&#xff08;此处以 Innodb 为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBase &am…

Ftrans数据摆渡系统 搭建安全便捷跨网文件传输通道

一、专业数据摆渡系统对企业的意义 专业的数据摆渡系统对企业具有重要意义&#xff0c;主要体现在以下几个方面‌&#xff1a; 1、‌数据安全性‌&#xff1a;数据摆渡系统通过加密传输、访问控制和审计日志等功能&#xff0c;确保数据在传输和存储过程中的安全性。 2、‌高…

FPGA的DMA应用——pcileech

硬件通过pcie总线&#xff0c;访存本机的内存&#xff0c;并进行修改&#xff0c;可以进行很多操作。 学习视频&#xff1a;乱讲DMA及TLP 1-pcileech项目简介和自定义模块介绍_哔哩哔哩_bilibili vivado2024.1的下载文章链接和地址&#xff1a;AMD-Xilinx Vivado™ 2024.1 现…

未来网络技术的新征程:5G、物联网与边缘计算(10/10)

一、5G 网络&#xff1a;引领未来通信新潮流 &#xff08;一&#xff09;5G 网络的特点 高速率&#xff1a;5G 依托良好技术架构&#xff0c;提供更高的网络速度&#xff0c;峰值要求不低于 20Gb/s&#xff0c;下载速度最高达 10Gbps。相比 4G 网络&#xff0c;5G 的基站速度…

一种寻路的应用

应用背景 利用长途车进行货物转运的寻路计算。例如从深圳到大连。可以走有很多条长途车的路线。需要根据需求计算出最合适路线。不同的路线的总里程数、总价、需要的时间不一样。客户根据需求进行选择。主要有一些细节&#xff1a; 全国的长途车车站的数据的更新&#xff1a; …

STL格式转换为GLTF格式

STL与GLTF格式简介 STL格式 STL&#xff08;Stereo Lithography&#xff09;文件是一种广泛使用的3D打印文件格式&#xff0c;由3D Systems公司开发。它主要用于存储三维物体的几何信息&#xff0c;常用于立体光刻等3D打印技术。STL文件通常只包含物体的表面几何形状&#xf…

DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(1)

DevOps实战&#xff1a;用Kubernetes和Argo打造自动化CI/CD流程&#xff08;1&#xff09; 架构 架构图 本设计方案的目标是在一台阿里云ECS服务器上搭建一个轻量级的Kubernetes服务k3s节点&#xff0c;并基于Argo搭建一套完整的DevOps CI/CD服务平台&#xff0c;包括Argo CD…

数据结构经典算法总复习(下卷)

第五章:树和二叉树 先序遍历二叉树的非递归算法。 void PreOrderTraverse(BiTree T, void (*Visit)(TElemType)) {//表示用于查找的函数的指针Stack S; BiTree p T;InitStack(S);//S模拟工作栈while (p || !StackEmpty(S)) {//S为空且下一个结点为空&#xff0c;意味着结束遍…

前端知识补充—CSS

CSS介绍 什么是CSS CSS(Cascading Style Sheet)&#xff0c;层叠样式表, ⽤于控制⻚⾯的样式 CSS 能够对⽹⻚中元素位置的排版进⾏像素级精确控制, 实现美化⻚⾯的效果. 能够做到⻚⾯的样式和结构分离 基本语法规范 选择器 {⼀条/N条声明} 1&#xff09;选择器决定针对谁修改…

Spring Security 6 系列之九 - 集成JWT

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级为6.3.0&#xff0c;关键是其风…

【Go】context标准库

文章目录 1. 概述1.1 什么是 Context1.2 设计原理1.3 使用场景1.4 Context 分类核心:Context接口2. 源码解读4个实现emptyCtxTODO 和 BackgroundcancelCtxWithCancelcancelCtx.propagateCancel 构建父子关联parentCancelCtx 获取父上下文中的内嵌cancelCtxcanceltimerCtxWithT…

Windows和Linux安全配置和加固

一.A模块基础设施设置/安全加固 A-1.登录加固 1.密码策略 a.最小密码长度不少于8个字符&#xff0c;将密码长度最小值的属性配置界面截图。 练习用的WindowsServer2008,系统左下角开始 > 管理工具 > 本地安全策略 > 账户策略 > 密码策略 > 密码最小长度&#…

webrtc-internals调试工具

Google 的 Chrome&#xff08;87 或更高版本&#xff09;WebRTC 内部工具是一套内置于 Chrome 浏览器中的调试工具; webrtc-internals 能够查看有关视频和音频轨道、使用的编解码器以及流的一般质量的详细信息。这些知识对于解决音频和视频质量差的问题非常有帮助。 webrtc-int…