面试题:什么是 React 中类组件和函数组件?它们有什么区别?

在 React 中,类组件(Class Component)函数组件(Function Component) 是定义 UI 组件的两种主要方式。随着 React Hooks 的引入,函数组件的功能大大增强,逐渐成为主流。


一、基本定义

1. 类组件 (Class Component)

  • 使用 ES6 的 class 语法定义。
  • 必须继承 React.Component
  • 通过 render() 方法返回 JSX。
  • 可以使用生命周期方法和 this.state 管理状态。

示例

import React, { Component } from 'react';

class Welcome extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  handleClick = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <h1>Hello, {this.props.name}</h1>
        <p>点击次数: {this.state.count}</p>
        <button onClick={this.handleClick}>点我</button>
      </div>
    );
  }
}

2. 函数组件 (Function Component)

  • 本质上是一个 JavaScript 函数。
  • 接收 props 作为参数。
  • 返回 JSX。
  • 在 React 16.8 之前是“无状态组件”,但 Hooks 的出现使其也能管理状态和副作用。

示例(使用 Hooks):

import React, { useState } from 'react';

function Welcome(props) {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <h1>Hello, {props.name}</h1>
      <p>点击次数: {count}</p>
      <button onClick={handleClick}>点我</button>
    </div>
  );
}

二、核心区别对比

特性类组件 (Class Component)函数组件 (Function Component)
语法基于 classextends基于普通函数
状态管理使用 this.statethis.setState()使用 useState, useReducer 等 Hook
生命周期提供完整的生命周期方法(componentDidMount, componentDidUpdate, componentWillUnmount 等)使用 useEffect Hook 模拟生命周期
this 关键字大量使用 this(如 this.state, this.props, this.method不需要 this,更简洁
性能略重,有实例化开销更轻量,性能稍优
可读性逻辑分散(状态、生命周期、渲染分离)逻辑更集中(相关逻辑靠近)
学习曲线需要理解 this、绑定、类等概念更简单直观,接近函数式编程
复用逻辑依赖 HOC(高阶组件)或 Render Props依赖自定义 Hooks,更灵活简洁

三、详细差异解析

1. 状态 (State)

  • 类组件:通过 this.state 初始化,通过 this.setState() 更新。更新是异步的,且会合并对象。
  • 函数组件:通过 useState Hook 声明状态。useState 返回一个数组 [state, setState]。更新函数不会合并对象,而是替换。
// 类组件 - setState 会合并对象
this.setState({ name: 'Alice' }); // 其他 state 属性保留

// 函数组件 - setPerson 替换整个对象
setPerson(prev => ({ ...prev, name: 'Alice' })); // 手动合并

2. 生命周期 vs Effect Hook

  • 类组件
    • componentDidMount: 组件挂载后执行(副作用)。
    • componentDidUpdate: 组件更新后执行。
    • componentWillUnmount: 组件卸载前清理。
  • 函数组件:统一使用 useEffect
useEffect(() => {
  // componentDidMount + componentDidUpdate
  console.log('组件挂载或更新');

  return () => {
    // componentWillUnmount
    console.log('组件将要卸载');
  };
}, []); // 依赖数组控制执行时机

3. 方法绑定 (Method Binding)

  • 类组件:事件处理函数中的 this 需要正确绑定,否则为 undefined
    • 解决方案:构造函数中绑定、箭头函数属性、或在 JSX 中使用箭头函数(不推荐,影响性能)。
  • 函数组件:没有 this,不存在绑定问题,更简单。

4. 逻辑复用

  • 类组件:使用 HOCRender Props,但容易导致“嵌套地狱”(Wrapper Hell)。
  • 函数组件:使用 自定义 Hooks,可以像调用函数一样复用状态逻辑,代码更扁平、清晰。
// 自定义 Hook
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  return width;
}

// 在任意组件中使用
function MyComponent() {
  const width = useWindowWidth();
  return <div>窗口宽度: {width}px</div>;
}

四、现代 React 的趋势

  • 官方推荐:React 官方强烈推荐使用函数组件 + Hooks
  • 未来方向:新的功能(如 Concurrent Mode)主要围绕函数组件设计。
  • 类组件地位:类组件不会被移除,但新项目应优先选择函数组件。

总结

对比维度类组件函数组件
本质JavaScript 类普通函数
状态this.state / setStateuseState / useReducer
副作用生命周期方法useEffect Hook
this必须处理无需处理
逻辑复用HOC / Render Props自定义 Hooks ✅
推荐程度❌ 旧项目维护✅ 新项目首选

一句话结论

函数组件 + Hooks 是现代 React 开发的标准和最佳实践。它语法更简洁、逻辑更集中、复用更灵活。除非维护旧代码,否则应优先使用函数组件。

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