react的组件分为类组件和函数组件

如题,react的组件分为类组件和函数组件。但二者有什么区别呢?

我刚开始的时候,无端的认为,只有类组件可以输出DOM,函数组件只能充当函数库之类的角色。但事实上,它们的功能是差不多的。从资料看,似乎是类组件先出现,后来才有的函数组件。二者最大的区别,也许是类组件比较笨重,函数组件比较轻盈,大有后来居上之势。类组件的优势,在于拥有时间周期事件函数,但函数组件也可以通过Hook函数实现相同的效果。

下面是二者的一些比较:

一、定义方式

在 React 中,类组件和函数组件是两种不同的组件定义方式。它们各有特点,适用于不同的场景。下面是它们之间的一些主要区别:

1. 类组件(Class Component)

类组件是使用 ES6 的类(class)语法定义的 React 组件。它们具有更复杂的功能,特别是在 React 16.8 之前,它们是唯一能够使用状态(state)和生命周期方法的组件。

特点:

使用 class 关键字定义,并继承自 React.Component。

能够使用 state 来管理组件的内部状态。

可以使用生命周期方法,如 componentDidMount、componentDidUpdate 和 componentWillUnmount 等。

通过 this.props 来访问传递给组件的属性(props)。

javascript 复制代码
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。

javascript 复制代码
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,会使用默认值。

javascript 复制代码
import React, { Component } from 'react';
import PropTypes from 'prop-types';

class MyClassComponent extends Component {
  // 定义 propTypes
  static propTypes = {
    message: PropTypes.string,
    count: PropTypes.number
  };

  // 定义 defaultProps
  static 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。

javascript 复制代码
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 包装

javascript 复制代码
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;

八.总结

类组件 vs. 函数组件

代码简洁性:函数组件通常比类组件更简洁。

状态管理:类组件通过 this.state 和 this.setState 管理状态,而函数组件使用 useState 钩子。

生命周期管理:类组件使用生命周期方法,而函数组件使用 useEffect 钩子(Hook)来管理副作用。

性能:函数组件在大多数情况下具有更好的性能,因为它们不需要 this 的绑定操作,并且在 React 的渲染机制中更容易优化。

类组件和函数组件都可以有效地构建 React 应用程序,但函数组件配合 Hooks 的使用已经成为了 React 社区中的主流趋势。函数组件因其简洁性和可维护性而受到青睐,而 Hooks 为函数组件提供了类似类组件的功能,同时也增加了更多的灵活性和可复用性。

随着React Hooks的引入,函数组件已经能够完成大部分类组件能做的事情,并且代码更简洁、更容易理解。因此,建议默认使用函数组件,特别是对于新项目或新功能开发。不过,在需要使用生命周期方法或维护遗留代码时,类组件仍然是合适的选择。

相关推荐
会蹦的鱼3 小时前
React学习day07-ReactRouter-抽象路由模块、路由导航、路由导航传参、嵌套路由、默认二级路由的设置、两种路由模式
javascript·学习·react.js
真的很上进10 小时前
【Git必看系列】—— Git巨好用的神器之git stash篇
java·前端·javascript·数据结构·git·react.js
大表哥615 小时前
在react中 使用redux
前端·react.js·前端框架
因为奋斗超太帅啦16 小时前
React学习笔记(三)——React 组件通讯
笔记·学习·react.js
西瓜本瓜@19 小时前
React + React Image支持图像的各种转换,如圆形、模糊等效果吗?
前端·react.js·前端框架
黄毛火烧雪下19 小时前
React 的 useEffect 钩子,执行一些异步操作来加载基本信息
前端·chrome·react.js
蓝莓味柯基19 小时前
React——点击事件函数调用问题
前端·javascript·react.js
资深前端之路19 小时前
react jsx
前端·react.js·前端框架
白鹭凡1 天前
react 甘特图之旅
前端·react.js·甘特图
Passion不晚1 天前
Vue vs React vs Angular 的对比和选择
vue.js·react.js·前端框架·angular.js