如题,react的组件分为类组件和函数组件。但二者有什么区别呢?
我刚开始的时候,无端的认为,只有类组件可以输出DOM,函数组件只能充当函数库之类的角色。但事实上,它们的功能是差不多的。从资料看,似乎是类组件先出现,后来才有的函数组件。二者最大的区别,也许是类组件比较笨重,函数组件比较轻盈,大有后来居上之势。类组件的优势,在于拥有时间周期事件函数,但函数组件也可以通过Hook函数实现相同的效果。
下面是二者的一些比较:
一、定义方式
在 React 中,类组件和函数组件是两种不同的组件定义方式。它们各有特点,适用于不同的场景。下面是它们之间的一些主要区别:
1. 类组件(Class Component)
类组件是使用 ES6 的类(class)语法定义的 React 组件。它们具有更复杂的功能,特别是在 React 16.8 之前,它们是唯一能够使用状态(state)和生命周期方法的组件。
特点:
使用 class 关键字定义,并继承自 React.Component。
能够使用 state 来管理组件的内部状态。
可以使用生命周期方法,如 componentDidMount、componentDidUpdate 和 componentWillUnmount 等。
通过 this.props 来访问传递给组件的属性(props)。
import React, { Component } from 'react';class MyComponent extends Component {constructor(props) {super(props);this.state = {count: 0};}increment = () => {this.setState({ count: this.state.count + 1 });}render() {return (<div><p>Count: {this.state.count}</p><button onClick={this.increment}>Increment</button></div>);}
}export default MyComponent;
2. 函数组件(Function Component)
函数组件是使用 JavaScript 函数定义的 React 组件。自 React 16.8 以来,函数组件通过引入 Hooks 可以实现状态管理和副作用处理,功能上已经与类组件基本等价。
特点:
使用 JavaScript 函数定义,通常是更简单和推荐的方式。
在函数组件中,无法直接使用 this,而是通过 Hooks(如> useState 和 useEffect)来管理状态和副作用。
更加简洁,通常用于无状态组件,但在有状态需求时也可以使用 Hooks。
import React, { useState } from 'react';function MyComponent() {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1);};return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button></div>);
}export default MyComponent;
二. 状态管理
类组件:
使用 this.state 来管理组件的状态。
使用 this.setState() 方法来更新状态。
可以在生命周期方法中使用 setState 来响应不同的事件。
函数组件:
使用 useState Hook 来管理状态。
使用 useReducer Hook 来管理更复杂的状态逻辑。
可以在函数组件内部使用多个 useState 或 useReducer 来管理不同的状态片段。
三. 生命周期方法
类组件:
提供了一系列的生命周期方法,如 componentDidMount, componentDidUpdate, componentWillUnmount 等。
可以在这些方法中执行副作用操作,如数据获取、订阅等。
函数组件:
使用 useEffect Hook 来执行副作用操作。
可以模拟类组件的生命周期方法,例如在 useEffect 中模拟 componentDidMount 和 componentDidUpdate。
四. 代码结构
类组件:
通常包含多个方法和生命周期钩子,可能会导致组件变得复杂。
需要更多样板代码(如构造函数、render 方法等)。
函数组件:
结构更简单,更易于理解和维护。
使用 Hooks 可以保持逻辑的一致性,使组件更加模块化。
五. 可复用性
类组件:
通常使用高阶组件(Higher Order Components, HOCs)或渲染属性模式来复用逻辑。
可能需要提取子类来复用逻辑。
函数组件:
使用 Hooks 如 useCallback, useMemo, useContext 等来复用逻辑。
可以定义自定义 Hooks 来封装复用的逻辑。
六. 性能考虑
类组件:
在某些情况下,可能会因为额外的实例方法和生命周期方法而稍微影响性能。
使用纯组件 (React.PureComponent) 可以提高性能,因为它会自动进行浅比较以避免不必要的重新渲染。
函数组件:
使用 React.memo 或 useMemo 可以提高性能,减少不必要的渲染。
使用 useCallback 可以确保函数引用的一致性,从而避免不必要的渲染。
七. 语法糖
在 React 中,propTypes 和 defaultProps 用于类型检查和为组件的 props 提供默认值。类组件和函数组件在使用这些特性时有些细微的区别。
类组件:
可以直接使用 propTypes 和 defaultProps。
propTypes:用于检查传入 props 的类型是否符合预期。
defaultProps:用于定义组件的默认 props 值,如果没有传递该 prop,会使用默认值。
import React, { Component } from 'react';
import PropTypes from 'prop-types';class MyClassComponent extends Component {// 定义 propTypesstatic propTypes = {message: PropTypes.string,count: PropTypes.number};// 定义 defaultPropsstatic defaultProps = {message: 'Hello',count: 0};render() {return (<div><p>{this.props.message}</p><p>{this.props.count}</p></div>);}
}export default MyClassComponent;
函数组件:
1)可以使用 PropTypes 作为单独的导入,或者使用 React.memo 的第二个参数来定义 propTypes 和 defaultProps。
import React from 'react';
import PropTypes from 'prop-types';function MyFunctionComponent(props) {return (<div><p>{props.message}</p><p>{props.count}</p></div>);
}// 定义 propTypes
MyFunctionComponent.propTypes = {message: PropTypes.string,count: PropTypes.number
};// 定义 defaultProps
MyFunctionComponent.defaultProps = {message: 'Hello',count: 0
};export default MyFunctionComponent;
2)使用 React.memo 包装
import React from 'react';
import PropTypes from 'prop-types';const MyFunctionComponent = React.memo(function(props) {return (<div><p>{props.message}</p><p>{props.count}</p></div>);
});// 定义 propTypes
MyFunctionComponent.propTypes = {message: PropTypes.string,count: PropTypes.number
};// 定义 defaultProps
MyFunctionComponent.defaultProps = {message: 'Hello',count: 0
};export default MyFunctionComponent;
八.this
在函数组件中不能使用 this,因为 this 是类组件的概念
九.总结
类组件 vs. 函数组件
代码简洁性:函数组件通常比类组件更简洁。
状态管理:类组件通过 this.state 和 this.setState 管理状态,而函数组件使用 useState 钩子。
生命周期管理:类组件使用生命周期方法,而函数组件使用 useEffect 钩子(Hook)来管理副作用。
性能:函数组件在大多数情况下具有更好的性能,因为它们不需要 this 的绑定操作,并且在 React 的渲染机制中更容易优化。
类组件和函数组件都可以有效地构建 React 应用程序,但函数组件配合 Hooks 的使用已经成为了 React 社区中的主流趋势。函数组件因其简洁性和可维护性而受到青睐,而 Hooks 为函数组件提供了类似类组件的功能,同时也增加了更多的灵活性和可复用性。
随着React Hooks的引入,函数组件已经能够完成大部分类组件能做的事情,并且代码更简洁、更容易理解。因此,建议默认使用函数组件,特别是对于新项目或新功能开发。不过,在需要使用生命周期方法或维护遗留代码时,类组件仍然是合适的选择。