导读:本期聚焦于小伙伴创作的《深入理解React createRef():为何不直接使用普通对象?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《深入理解React createRef():为何不直接使用普通对象?》有用,将其分享出去将是对创作者最好的鼓励。

在React组件开发中,ref是用于获取组件实例或者DOM元素的重要API,官方提供了createRef()方法来创建ref对象,但不少开发者会尝试用普通对象{ current: null }来替代,这种做法看似可行,实际会埋下很多隐患。本文将详细分析两者的差异,解释为什么不能直接使用普通对象。

深入理解React createRef():为何不直接使用普通对象?

普通对象创建ref的问题

首先我们来看直接使用普通对象作为ref的场景,假设我们有一个类组件,尝试用普通对象绑定input元素:

import React, { Component } from 'react';

class NormalRefDemo extends Component {
  constructor(props) {
    super(props);
    // 使用普通对象作为ref
    this.inputRef = { current: null };
  }

  componentDidMount() {
    console.log('普通对象ref的current值:', this.inputRef.current);
    // 尝试让input自动聚焦
    if (this.inputRef.current) {
      this.inputRef.current.focus();
    }
  }

  render() {
    return (
      <div>
        <input type="text" ref={this.inputRef} />
        <button onClick={() => this.inputRef.current.focus()}>聚焦输入框</button>
      </div>
    );
  }
}

export default NormalRefDemo;

运行上述代码后,你会发现组件挂载完成后,this.inputRef.current依然是null,点击按钮也无法触发聚焦,这是因为普通对象没有和React的更新流程绑定。

createRef()的工作原理

React的createRef()方法创建的是一个特殊的ref对象,这个对象会被React内部识别,在组件渲染、更新、卸载的不同阶段,React会自动对ref的current属性进行赋值和清理。我们来看使用createRef()的正确示例:

import React, { Component, createRef } from 'react';

class CreateRefDemo extends Component {
  constructor(props) {
    super(props);
    // 使用createRef创建ref
    this.inputRef = createRef();
  }

  componentDidMount() {
    console.log('createRef创建的ref的current值:', this.inputRef.current);
    // 自动聚焦成功
    if (this.inputRef.current) {
      this.inputRef.current.focus();
    }
  }

  render() {
    return (
      <div>
        <input type="text" ref={this.inputRef} />
        <button onClick={() => this.inputRef.current.focus()}>聚焦输入框</button>
      </div>
    );
  }
}

export default CreateRefDemo;

这段代码运行后,组件挂载完成时this.inputRef.current会正确指向input DOM元素,点击按钮也能正常触发聚焦。

核心差异对比

我们可以通过下表清晰看到普通对象和createRef()创建ref的核心区别:

对比维度普通对象refcreateRef()创建ref
是否被React内部识别
渲染时是否自动赋值current
组件卸载时是否自动清理current
是否支持跨渲染周期保持引用稳定不稳定,可能被重新创建稳定,引用不会随渲染变化

为什么普通对象无法被赋值

React在处理ref的时候,会判断传入的ref是否是合法的ref对象,只有createRef()或者useRef()创建的ref才会被React的协调器处理,在DOM元素渲染完成后,将对应的DOM实例或者组件实例赋值给ref的current属性。普通对象没有这个标识,React会直接忽略对它的赋值操作,所以current始终为初始值null。

另外,当组件卸载时,createRef()创建的ref会自动将current设置为null,避免内存泄漏,而普通对象不会触发这个清理逻辑,如果后续代码还持有这个普通对象的引用,可能会导致访问到已经卸载的组件实例,引发异常。

函数组件中的ref使用

在函数组件中,我们通常使用useRef()来创建ref,它的原理和createRef()类似,同样不能直接用普通对象替代:

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

function FunctionRefDemo() {
  // 使用useRef创建ref,不能用{ current: null }替代
  const inputRef = useRef(null);

  useEffect(() => {
    console.log('函数组件中ref的current值:', inputRef.current);
    inputRef.current.focus();
  }, []);

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={() => inputRef.current.focus()}>聚焦输入框</button>
    </div>
  );
}

export default FunctionRefDemo;

如果在函数组件中用普通对象作为ref,同样会出现current无法赋值的问题,因为每次组件渲染时,普通对象都会被重新创建,之前的引用也会丢失,无法正确绑定到DOM元素上。

总结

createRef()和useRef()是React专门为ref场景设计的API,它们创建的ref对象会和React的整个生命周期绑定,保证ref的赋值、清理、引用稳定都符合React的运行逻辑。普通对象没有这些特性,直接使用会导致ref无法正确绑定、组件更新异常、内存泄漏等问题,因此在React开发中,应当始终使用官方提供的createRef()或者useRef()来创建ref,避免不必要的bug。

ReactcreateRefref普通对象组件实例修改时间:2026-07-15 22:30:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。