React Class 组件与函数组件全方位对比
文章目录
- 一、定义方式和语法结构
- 二、状态管理(State)
- 三、生命周期方法(Lifecycle Methods)
- 四、性能优化
- 五、上下文使用
- 六、事件绑定
- 七、渲染机制与性能差异基础
- 八、代码可读性和简洁性
一、定义方式和语法结构
- Class组件
- 使用ES6的
class
关键字来定义,并且需要继承React.Component
。 - 例如:
import React, { Component } from 'react'; class MyClassComponent extends Component { render() { return <div>Class Component</div>; } }
- 使用ES6的
- 函数组件
- 使用函数来定义,函数接收
props
作为参数,并且返回一个React元素。 - 例如:
import React from 'react'; function MyFunctionComponent(props) { return <div>Function Component</div>; }
- 使用函数来定义,函数接收
二、状态管理(State)
- Class组件
- 有自己的内部状态(
state
),通过this.state
来访问,并且可以通过this.setState()
方法来更新状态。 - 状态初始化通常在
constructor
中进行。 - 例如:
class MyClassComponent extends Component { constructor(props) { super(props); this.state = { count: 0 }; } incrementCount = () => { this.setState(prevState => ({ count: prevState.count + 1 })); } render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={this.incrementCount}>Increment</button> </div> ); } }
- 有自己的内部状态(
- 函数组件
- 在早期版本中没有自己的状态,但从React 16.8引入Hooks后,可以使用
useState
钩子来添加状态。 - 例如:
import React, { useState } from 'react'; function MyFunctionComponent() { const [count, setCount] = useState(0); const incrementCount = () => { setCount(prevCount => prevCount + 1); } return ( <div> <p>Count: {count}</p> <button onClick={incrementCount}>Increment</button> </div> ); }
- 在早期版本中没有自己的状态,但从React 16.8引入Hooks后,可以使用
三、生命周期方法(Lifecycle Methods)
- Class组件
- 有一系列的生命周期方法,如
componentDidMount
、componentDidUpdate
、componentWillUnmount
等,用于在组件的不同阶段执行特定操作。 - 例如:
class MyClassComponent extends Component { componentDidMount() { console.log('Component did mount'); } componentDidUpdate() { console.log('Component did update'); } componentWillUnmount() { console.log('Component will unmount'); } render() { return <div>Class Component</div>; } }
- 有一系列的生命周期方法,如
- 函数组件
- 在没有Hooks之前没有生命周期方法,但使用Hooks后,可以通过
useEffect
钩子来模拟生命周期行为。 - 例如:
import React, { useEffect } from 'react'; function MyFunctionComponent() { useEffect(() => { console.log('Component did mount'); return () => { console.log('Component will unmount'); }; }, []); return <div>Function Component</div>; }
- 在没有Hooks之前没有生命周期方法,但使用Hooks后,可以通过
四、性能优化
- Class组件
- 通常通过
shouldComponentUpdate
生命周期方法来进行性能优化,决定组件是否需要重新渲染。 - 例如:
class MyClassComponent extends Component { shouldComponentUpdate(nextProps, nextState) { // 只在count改变时重新渲染 return this.state.count!== nextState.count; } render() { return <div>Class Component</div>; } }
- 通常通过
- 函数组件
- 使用
React.memo
高阶组件或者useMemo
、useCallback
钩子来进行性能优化。 - 例如:
import React, { useState, useCallback, memo } from 'react'; const MyFunctionComponent = memo(({ count }) => { return <div>Function Component - Count: {count}</div>; }); function ParentComponent() { const [count, setCount] = useState(0); const incrementCount = useCallback(() => { setCount(prevCount => prevCount + 1); }, []); return ( <div> <MyFunctionComponent count={count} /> <button onClick={incrementCount}>Increment</button> </div> ); }
- 使用
五、上下文使用
- Class组件
- 使用
this.context
来访问上下文数据,并且需要定义contextType
属性来指定上下文的类型。 - 例如:
import React, { Component } from 'react'; class MyClassComponent extends Component { static contextTypes = { theme: PropTypes.string }; render() { return <div>Theme: {this.context.theme}</div>; } }
- 使用
- 函数组件
- 使用
useContext
钩子来访问上下文数据。 - 例如:
import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); function MyFunctionComponent() { const theme = useContext(ThemeContext); return <div>Theme: {theme}</div>; }
- 使用
六、事件绑定
- Class组件
- 事件绑定通常在
constructor
中进行,或者使用类字段属性来绑定。 - 例如:
class MyClassComponent extends Component { constructor(props) { super(props); this.handleClick = this.handleClick.bind(this); } handleClick() { console.log('Button clicked'); } render() { return <button onClick={this.handleClick}>Click me</button>; } }
- 或者使用类字段属性(需要Babel插件支持):
class MyClassComponent extends Component { handleClick = () => { console.log('Button clicked'); } render() { return <button onClick={this.handleClick}>Click me</button>; } }
- 事件绑定通常在
- 函数组件
- 事件绑定直接在函数内部定义,无需额外的绑定操作。
- 例如:
function MyFunctionComponent() { const handleClick = () => { console.log('Button clicked'); }; return <button onClick={handleClick}>Click me</button>; }
七、渲染机制与性能差异基础
- Class组件
- Class组件基于类的继承来构建,有自己的生命周期方法。在每次更新时,它会根据
shouldComponentUpdate
生命周期方法的返回值来决定是否重新渲染。如果没有实现shouldComponentUpdate
,只要父组件重新渲染或者自身的state
、props
有变化,组件就会重新渲染。 - 例如,在一个有多个子组件的父组件中,如果一个无关子组件的
state
变化导致父组件重新渲染,那么没有优化的Class子组件也会跟着重新渲染。
- Class组件基于类的继承来构建,有自己的生命周期方法。在每次更新时,它会根据
- 函数组件
- 函数组件本身是无状态的(在没有Hooks之前),在React 16.8引入Hooks后,可以使用
useState
、useEffect
等Hooks来处理状态和副作用。函数组件的重新渲染取决于其依赖项的变化。 - 例如,使用
React.memo
高阶组件可以对函数组件进行简单的性能优化,它类似于Class组件中的shouldComponentUpdate
,会对props
进行浅比较,只有props
变化时才重新渲染。
- 函数组件本身是无状态的(在没有Hooks之前),在React 16.8引入Hooks后,可以使用
八、代码可读性和简洁性
- Class组件
- 由于有较多的模板代码(如
constructor
、super
、生命周期方法等),代码可能相对冗长。
- 由于有较多的模板代码(如
- 函数组件
- 特别是在使用Hooks后,代码通常更加简洁和直观,能够以更函数式的风格编写。