面试题:什么是 React 的实例?函数式组件是否有实例?

这是一道考察对 React 运行机制 理解深度的好题,尤其是对 函数式组件本质 的认知。

下面从概念、类组件 vs 函数组件、以及面试陷阱三个层次来拆解。


一、什么是 React 的“实例”?

在 React 中,实例(Instance) 特指:

使用 React.ComponentReact.PureComponent 创建的类组件,在渲染时由 React 内部生成的组件实例对象。

这个实例对象:

  • 是通过 new YourComponent(props) 创建的。
  • 拥有完整的生命周期方法(componentDidMount 等)。
  • 拥有实例属性(如 this.statethis.propsthis.refs)。
  • 可以调用实例方法(如 this.setState())。

示例:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myProperty = 'hello'; // 实例属性
  }
  myMethod() {                // 实例方法
    console.log('method called');
  }
  render() {
    return <div>Class Component</div>;
  }
}

// React 内部大致做了:
const instance = new MyComponent(props);
instance.componentWillMount?.();
instance.render();

这个 instance 就是实例


二、函数式组件是否有实例?

直接结论:

函数式组件没有实例。

原因分析:

  1. 不是通过 new 调用的
    类组件被 React 内部用 new 实例化,而函数组件就是一个普通函数,React 直接调用它,不会创建实例对象。
  2. 没有 this
    函数组件没有自己的 this(严格模式下 thisundefined)。
  3. 没有实例属性和方法
    你不能在函数组件上挂载 this.xxx = yyy,也没有生命周期方法。
  4. React 内部也没有为函数组件创建实例对象
    在 React Fiber 架构中,函数组件的 Fiber 节点上不会挂载一个像类组件那样的实例对象。

三、那“函数组件用起来像有实例”是怎么回事?

很多人会产生困惑:函数组件明明可以保存状态(useState)、执行副作用(useEffect),这看起来不是和实例类似吗?

关键点:

  • Hook 保存的状态不是挂在“实例”上,而是挂在 React Fiber 节点上
    Fiber 是 React 内部用来管理组件工作的数据结构,每个组件(无论是类还是函数)都对应一个 Fiber 节点。
  • 函数组件每次渲染都是重新执行整个函数,Hooks 通过闭包和链表从 Fiber 节点读取/写入数据。
  • 所以:
    • 类组件的状态存在 组件实例对象 中。
    • 函数组件的状态存在 Fiber 节点 中(与实例不同)。

四、对比总结表

特性类组件函数组件
是否有实例✅ 有(React 内部 new 出来的对象)❌ 没有
能否使用 this✅ 可以❌ 没有 this
状态存储位置实例对象上(this.stateFiber 节点上(Hook 链表)
生命周期方法✅ 有❌ 无(但可以用 useEffect 模拟)
实例方法✅ 可以定义❌ 不能
渲染方式调用 render() 方法执行函数体

五、面试中的“陷阱”与进阶回答

常见追问 1:“那 ref 可以获取函数组件的实例吗?”

答:

  • 对函数组件使用 ref,默认不会获取到实例(因为没有)。
  • 如果要获取函数组件内部某个 DOM 或值,需要使用 useImperativeHandle + forwardRef 暴露自定义的方法/属性。

常见追问 2:“既然没有实例,那为什么 React 还要支持函数组件?”

答:

  • 没有实例 → 更轻量,减少内存占用。
  • 没有 this → 避免绑定困扰,更易理解和测试。
  • Hooks 让逻辑复用比 HOC / Render Props 更简洁。
  • 符合函数式编程范式,利于未来编译优化(如 Auto Memoization)。

常见追问 3:“React 内部如何区分函数组件和类组件?”

答:
通过原型链判断:

if (Component.prototype && Component.prototype.isReactComponent) {
  // 类组件
} else {
  // 函数组件
}

类组件原型上有 isReactComponent 标记。


六、面试参考答案(精简版)

“React 的实例指的是类组件被 new 之后生成的对象,它拥有 this.statethis.props、生命周期方法等。
函数式组件没有实例,因为它只是一个普通函数,不会被实例化。函数组件的状态和副作用是通过 Hooks 存储在 React 内部的 Fiber 节点上,而不是实例对象中。这也是函数组件更轻量、无需绑定 this 的原因。”

THE END
喜欢就支持一下吧
点赞5 分享