当前位置: 首页 > article >正文

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>;
        }
      }
      
  • 函数组件
    • 使用函数来定义,函数接收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>
        );
      }
      

三、生命周期方法(Lifecycle Methods)

  • Class组件
    • 有一系列的生命周期方法,如componentDidMountcomponentDidUpdatecomponentWillUnmount等,用于在组件的不同阶段执行特定操作。
    • 例如:
      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>;
      }
      

四、性能优化

  • Class组件
    • 通常通过shouldComponentUpdate生命周期方法来进行性能优化,决定组件是否需要重新渲染。
    • 例如:
      class MyClassComponent extends Component {
        shouldComponentUpdate(nextProps, nextState) {
          // 只在count改变时重新渲染
          return this.state.count!== nextState.count;
        }
      
        render() {
          return <div>Class Component</div>;
        }
      }
      
  • 函数组件
    • 使用React.memo高阶组件或者useMemouseCallback钩子来进行性能优化。
    • 例如:
      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,只要父组件重新渲染或者自身的stateprops有变化,组件就会重新渲染。
    • 例如,在一个有多个子组件的父组件中,如果一个无关子组件的state变化导致父组件重新渲染,那么没有优化的Class子组件也会跟着重新渲染。
  • 函数组件
    • 函数组件本身是无状态的(在没有Hooks之前),在React 16.8引入Hooks后,可以使用useStateuseEffect等Hooks来处理状态和副作用。函数组件的重新渲染取决于其依赖项的变化。
    • 例如,使用React.memo高阶组件可以对函数组件进行简单的性能优化,它类似于Class组件中的shouldComponentUpdate,会对props进行浅比较,只有props变化时才重新渲染。

八、代码可读性和简洁性

  • Class组件
    • 由于有较多的模板代码(如constructorsuper、生命周期方法等),代码可能相对冗长。
  • 函数组件
    • 特别是在使用Hooks后,代码通常更加简洁和直观,能够以更函数式的风格编写。

http://www.kler.cn/a/465606.html

相关文章:

  • Easticsearch介绍|实战?
  • 计算机的错误计算(二百零二)
  • MYSQL--------选择合适的数据类型
  • 【Yarn】通过JMX采集yarn相关指标的Flink任务核心逻辑
  • vip与haproxy构建nginx高可用集群传递客户端真实ip
  • Spring Boot 3 实现 MySQL 主从数据库之间的数据同步
  • 网关的主要类型和它们的特点
  • [网络安全] DVWA之 Open HTTP Redirect 攻击姿势及解题详析合集
  • AI机器人与政务服务机器人的服务局限问题分析
  • vue2、element的el-select 选项框的宽度设置、文本过长问题
  • 企业微信——智能表格学习
  • 实战项目模块之1------单个按键短按切换不同工作模式
  • 《HarmonyOS第一课》焕新升级,赋能开发者快速掌握鸿蒙应用开发
  • 【前端系列】Pinia状态管理库
  • 测试岗位面试常见的数据库问题及解答
  • gitlab高级功能之 CICD Steps
  • 微前端Webpack集成Vite子应用避坑指南
  • 微信小程序获取后端数据
  • PS4代理伺服器指南
  • JavaScript 基础2
  • 【网络安全】PostMessage:分析JS实现XSS
  • .e01, ..., .e0n的分卷压缩包怎么解压
  • 多目标优化算法——基于分解的多目标进化算法(MOEA-D)
  • [C++]vector(超详细)
  • Docker入门常用命令总结
  • 软考教材重点内容 信息安全工程师 第 12 章网络安全审计技术原理与应用