九江市网站建设_网站建设公司_SSG_seo优化
2026/1/21 23:59:31 网站建设 项目流程

你想了解的类组件(Class Component)和函数式组件(Functional Component)是 React 中两种核心的组件编写方式,前者是 React 早期的主流方案,后者则在 Hooks 推出后成为官方推荐的首选。本文会从语法结构、状态管理、生命周期、性能、使用场景等维度,帮你理清二者的核心区别,以及不同场景下的选型思路。

一、核心定义与语法差异

1. 类组件(Class Component)

类组件是基于 ES6 类语法创建的组件,必须继承React.ComponentReact.PureComponent,并通过render()方法返回 JSX。

jsx

import React from 'react'; // 类组件示例 class ClassCounter extends React.Component { // 构造函数:初始化状态、绑定方法 constructor(props) { super(props); // 初始化state this.state = { count: 0 }; // 手动绑定this(避免回调中this丢失) this.handleIncrement = this.handleIncrement.bind(this); } // 自定义方法 handleIncrement() { // 修改状态(必须用setState) this.setState({ count: this.state.count + 1 }); } // 必须实现render方法 render() { return ( <div> <p>计数:{this.state.count}</p> <button onClick={this.handleIncrement}>+1</button> </div> ); } }

2. 函数式组件(Functional Component)

函数式组件本质是一个普通的 JavaScript 函数,接收props作为参数,直接返回 JSX。Hooks(React 16.8+)推出后,函数式组件才具备了状态管理和生命周期能力。

jsx

import React, { useState } from 'react'; // 函数式组件示例 function FunctionalCounter(props) { // 用useState Hook管理状态 const [count, setCount] = useState(0); // 自定义方法(无需绑定this) const handleIncrement = () => { // 直接修改状态 setCount(count + 1); }; // 直接返回JSX,无需render方法 return ( <div> <p>计数:{count}</p> <button onClick={handleIncrement}>+1</button> </div> ); }

二、核心区别对比

为了让你更清晰地对比,我整理了关键维度的差异表:

对比维度类组件(Class Component)函数式组件(Functional Component)
语法结构基于 ES6 Class,需继承 React.Component普通 JS 函数,语法更简洁,无冗余代码
状态管理this.statesetState()管理状态useState/useReducerHooks 管理状态
this 指向存在 this,需手动绑定(或用箭头函数)无 this,避免 this 指向混乱问题
生命周期有明确的生命周期方法(componentDidMount 等)useEffectHook 模拟所有生命周期逻辑
性能优化可继承PureComponent或实现shouldComponentUpdateReact.memo(浅比较 props)+useMemo/useCallback优化
代码复用依赖高阶组件(HOC)、Render Props依赖 Hooks(更简洁,无嵌套地狱)
错误边界仅类组件可作为错误边界(实现 componentDidCatch)无法直接作为错误边界(需包裹类组件)
官方推荐仅兼容老项目,不推荐新开发React 16.8 + 官方首选方案

三、关键能力深度解析

1. 状态管理差异

类组件
  • 状态是对象形式this.state = { count: 0, name: 'test' }
  • 修改状态必须用setState(),且setState异步更新(合成事件中),可能需要依赖前一个状态:

    jsx

    // 正确:依赖前状态更新 this.setState(prevState => ({ count: prevState.count + 1 }));
  • 无法在函数中直接捕获最新状态(需用 ref 或 setState 回调)。
函数式组件
  • 状态可以是任意类型(数字、字符串、对象、数组等),useState按需求拆分:

    jsx

    const [count, setCount] = useState(0); const [user, setUser] = useState({ name: '张三' });
  • setState直接替换(而非合并),更新对象 / 数组时需手动合并:

    jsx

    // 更新对象:合并原有属性 setUser(prev => ({ ...prev, age: 25 }));
  • 能通过闭包直接捕获最新状态(但需注意依赖项问题)。

2. 生命周期模拟(函数式组件 vs 类组件)

类组件的生命周期方法在函数式组件中都能通过useEffect模拟,对应关系如下:

类组件生命周期函数式组件实现方式
componentDidMountuseEffect (() => { /* 逻辑 */ }, [])
componentDidUpdateuseEffect (() => { /* 逻辑 */ }, [依赖项])
componentWillUnmountuseEffect (() => { return () => { /* 清理 */ } }, [])
componentDidMount + componentDidUpdateuseEffect (() => { /* 逻辑 */ })

示例:模拟类组件的生命周期

jsx

// 函数式组件模拟生命周期 function LifecycleDemo() { const [count, setCount] = useState(0); // componentDidMount:仅挂载时执行 useEffect(() => { console.log('组件挂载'); // componentWillUnmount:清理函数 return () => { console.log('组件卸载'); }; }, []); // componentDidUpdate:count变化时执行 useEffect(() => { console.log('count更新为:', count); }, [count]); return ( <div> <p>{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); }

3. 性能优化差异

类组件优化
  • 继承React.PureComponent:自动对propsstate浅比较,避免不必要的重渲染;
  • 手动实现shouldComponentUpdate:自定义比较逻辑,返回false阻止重渲染。
函数式组件优化
  • React.memo:高阶组件,对props做浅比较,类似PureComponent
  • useMemo:缓存计算结果,避免每次渲染重复计算;
  • useCallback:缓存函数引用,避免因函数重新创建导致子组件重渲染。

示例:函数式组件性能优化

jsx

// React.memo:浅比较props const MemoizedChild = React.memo(({ onIncrement }) => { console.log('子组件渲染'); return <button onClick={onIncrement}>+1</button>; }); function Parent() { const [count, setCount] = useState(0); // useCallback:缓存函数引用 const handleIncrement = useCallback(() => { setCount(count + 1); }, [count]); // useMemo:缓存计算结果 const doubleCount = useMemo(() => { return count * 2; }, [count]); return ( <div> <p>计数:{count},双倍:{doubleCount}</p> <MemoizedChild onIncrement={handleIncrement} /> </div> ); }

四、使用场景与选型建议

1. 优先使用函数式组件的场景

  • 新项目开发:React 官方推荐,代码更简洁、易维护;
  • 需要复用逻辑:Hooks(如useStateuseEffect、自定义 Hook)比 HOC/Render Props 更优雅;
  • 团队协作:降低学习成本(无需理解 this、生命周期),减少 bug;
  • 性能敏感场景:通过React.memo+useCallback/useMemo可精准优化。

2. 仍需使用类组件的场景

  • 维护老项目:老代码基于类组件,无需强行重构;
  • 实现错误边界:函数式组件无法直接实现componentDidCatch,需用类组件:

    jsx

    class ErrorBoundary extends React.Component { state = { hasError: false }; static getDerivedStateFromError() { return { hasError: true }; } componentDidCatch(error, info) { console.log('捕获错误:', error, info); } render() { if (this.state.hasError) { return <div>出错了!</div>; } return this.props.children; } } // 使用:包裹函数式组件 <ErrorBoundary> <FunctionalComponent /> </ErrorBoundary>
  • 极少数复杂场景:如需要深度定制shouldComponentUpdate且 Hooks 优化成本更高。

五、迁移指南(类组件 → 函数式组件)

如果需要将类组件迁移为函数式组件,可遵循以下步骤:

  1. 替换类定义为函数:移除classextends React.Component,改为函数接收props
  2. 替换 state:将this.state拆分为多个useState
  3. 替换生命周期:用useEffect模拟componentDidMount/DidUpdate/WillUnmount
  4. 移除 this 绑定:函数内方法无需绑定 this,直接定义箭头函数或普通函数;
  5. 替换 this.props:直接使用函数参数props
  6. 性能优化:用React.memo替代PureComponentuseCallback/useMemo替代手动优化。

迁移示例

jsx

// 类组件 class OldComponent extends React.Component { state = { text: '' }; componentDidMount() { console.log('挂载'); } handleChange = (e) => { this.setState({ text: e.target.value }); }; render() { return <input value={this.state.text} onChange={this.handleChange} />; } } // 迁移后的函数式组件 function NewComponent(props) { const [text, setText] = useState(''); useEffect(() => { console.log('挂载'); }, []); const handleChange = (e) => { setText(e.target.value); }; return <input value={text} onChange={handleChange} />; } // 性能优化:添加React.memo const MemoizedNewComponent = React.memo(NewComponent);

总结

  1. 核心差异:类组件基于 ES6 Class,依赖this和生命周期方法;函数式组件是纯函数,依赖 Hooks 实现状态和生命周期,语法更简洁、无 this 陷阱。
  2. 选型原则:新项目优先用函数式组件 + Hooks,老项目 / 错误边界场景保留类组件。
  3. 优化方式:类组件用PureComponent/shouldComponentUpdate,函数式组件用React.memo+useCallback/useMemo

掌握二者的区别和选型思路,能让你在 React 开发中更灵活地选择合适的组件形式,写出更高效、易维护的代码。

👉 **觉得有用的点点关注谢谢~**

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询