”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > React 组件:类与函数式。

React 组件:类与函数式。

发布于2024-08-05
浏览:536

React Components: Class vs Functional.

我的 React 之旅始于四年前的功能组件和 Hooks。然后是'Siswe,他是训练营的参与者,也是我们常驻班的组件爱好者。当我们其他人在使用功能组件的团队项目上进行协作时,“Siswe 坚定不移地忠诚于类组件。

组件是用户界面 (UI) 的构建块。

将它们视为乐高积木 - 您可以以各种方式组合它们来创建复杂的结构。它们是封装 UI 和逻辑的独立且可重用的代码片段。

在另一个组件中重用一个组件通常如下所示:

import MyComponent from './MyComponent';

function ParentComponent() {
  return (
    
); }

类组件和功能组件是在 React 中创建组件的两种主要方式。

import React, { Component } from 'react';

class Counter extends Component {
 constructor(props) {
  super(props);
  this.state = { count: 0 };
 }

 handleClick = () => {
  this.setState({  
 count: this.state.count   1 });
 };

 render() {
  return  
 (
   
    

You clicked {this.state.count} times

        
  );  } } export default Counter;

这是一个类组件,使用扩展 React.Component 类的 JavaScript 类创建。

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count   1);
  };

  return (
    

You clicked {count} times

); } export default Counter;

另一方面,这是一个函数组件,编写为简单的 JavaScript 函数。

状态管理:核心区别。

类组件使用 this.state 管理它们自己的内部状态。这通常在构造函数中初始化,使用 this.state 对象访问,并使用 this.setState 方法更新,如上面的代码块所示。

功能组件最初是无状态的。但随着 Hooks 的引入,他们获得了管理状态和生命周期逻辑的能力。利用 useState 挂钩来管理状态,它返回一对值:当前状态和更新它的函数,如上所示。这对于简单的状态管理来说已经足够了。对于涉及多个子值的更复杂的状态逻辑,或者当下一个状态依赖于前一个状态时,您需要使用 useReducer.
例如:

import React, { useReducer } from 'react';

const initialState = {
  count: 0,
  step: 1,
};

const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count   state.step };
    case 'decrement':   

      return { ...state, count: state.count - state.step };
    case 'setStep':
      return { ...state, step: action.payload   
 };
    default:
      throw new Error();
  }
};

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const increment = () => dispatch({ type: 'increment' });
  const decrement = () => dispatch({ type: 'decrement'   
 });
  const setStep = (newStep) => dispatch({ type: 'setStep', payload: newStep });

  return (
    

Count: {state.count}

Step: {state.step}

setStep(Number(e.target.value))} />
); } export default Counter;

这里,useReducer以结构化且可维护的方式管理多个状态值和复杂的更新逻辑。 Hooks 专门用于功能组件。

避免直接操作两个组件中的状态对象。

无论组件类型如何,都不要直接修改或改变状态对象。相反,使用更新的值创建一个新对象。这种方法有助于 React 有效地跟踪更改并优化重新渲染。

功能组件示例:

import React, { useState } from 'react';

function UserProfile() {
  const [user, setUser] = useState({ name: 'Jane Doe', age: 30 });

  const handleNameChange = (newName) => {
    setUser({ ...user, name: newName }); // Create a new object with updated name
  };

  return (
    

Name: {user.name}

Age: {user.age}

handleNameChange(e.target.value)} />
); } export default UserProfile;

类组件示例:

import React, { Component } from 'react';

class UserProfile extends Component {
  state = { user: { name: 'Jane Doe', age: 30 } };

  handleNameChange = (newName) => {
    this.setState(prevState => ({
      user: { ...prevState.user, name: newName } // Create a new object with updated name
    }));
  };

  render() {
    return (
      

Name: {this.state.user.name}

Age: {this.state.user.age}

this.handleNameChange(e.target.value)} />
); } } export default UserProfile;

在这两个示例中,我们更新用户对象的 name 属性,同时保留原始对象的完整性。这确保了创建新的状态对象,保持不变性并防止状态更新的潜在问题。遵守这一点可确保可预测的行为、性能优化和更轻松的调试。

类组件用于复杂的逻辑。

  • 复杂的状态管理:在处理需要细粒度控制的复杂状态逻辑时,带有 this.state 和 this.setState 的类组件可以提供更大的灵活性。
  • 生命周期方法: 对于严重依赖生命周期方法(如 componentDidMount、componentDidUpdate 或 componentWillUnmount)的组件,类组件是传统的选择。
  • 错误边界:为了处理组件树中的错误并防止崩溃,带有 componentDidCatch 的类组件是必不可少的。
  • 性能优化:在特定的性能关键场景中,可以利用类组件中的PureComponent或shouldComponentUpdate。
  • 遗留代码库:如果您正在开发一个严重依赖类组件的现有项目,那么通过将它们用于新组件可能会更容易保持一致性。

功能组件用于简单视图。

  • 简单组件:对于具有最少状态或逻辑的表示组件,功能组件由于其简单性和可读性通常是首选。
  • 使用 Hooks 进行状态管理: 在功能组件中利用 useState 和 useReducer 提供了一种强大而灵活的状态管理方式。
  • 副作用: useEffect 挂钩允许管理副作用,例如数据获取、订阅或手动 DOM(文档对象模型)操作。
  • 性能优化: useMemo 和 useCallback 可以用来优化功能组件中的性能。

让您的组件需求指导您的决定。

函数式方法通常被认为更简洁和可读,并且由于简单和高效而通常就足够了。然而,类组件提供了对状态管理和生命周期方法的更多控制,特别是在处理复杂的逻辑或性能优化时。这意味着组织复杂逻辑的更好结构。

类组件和功能组件之间的选择并不总是明确的,因为没有严格的规则。评估组件的要求并选择最适合您的项目要求的类型。

您更喜欢使用哪个组件?

版本声明 本文转载于:https://dev.to/taiwocodes/react-components-class-vs-functional-5ebm?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何使用触发器和UDF从MySQL 5.1发送动态电子邮件通知?
    如何使用触发器和UDF从MySQL 5.1发送动态电子邮件通知?
    如何从mysql 5.1 使用SMTP和OUTFILE 在test.emaildrop上插入之前,请创建触发test.autosendfromdrop 每行开始 /*在此处启动电子邮件文件的写作*/ 选择 concat(“ to:”,new.to), con...
    编程 发布于2025-02-07
  • 大批
    大批
    [2 数组是对象,因此它们在JS中也具有方法。 切片(开始):在新数组中提取部分数组,而无需突变原始数组。 令arr = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    编程 发布于2025-02-07
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    在这里工作/},false); 不幸的是,答案是否。除非在Creation中存储对处理程序的引用。要解决此问题,请考虑将事件处理程序存储在中心位置,例如页面的主要对象,请考虑将事件处理程序存储在中心位置,否则无法清理匿名事件处理程序。 。这允许在需要时轻松迭代和清洁处理程序。
    编程 发布于2025-02-07
  • 在映射到MySQL枚举列时,如何确保冬眠保留值?
    在映射到MySQL枚举列时,如何确保冬眠保留值?
    在hibernate中保存枚举值:故障排除错误的列type ,他们各自的映射至关重要。在Java中使用枚举类型时,至关重要的是,建立冬眠的方式如何映射到基础数据库。在您的情况下,您已将MySQL列定义为枚举,并在Java中创建了相应的枚举代码。但是,您遇到以下错误:“ MyApp中的错误列类型。...
    编程 发布于2025-02-07
  • \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    使用(1)而不是(;;)会导致无限循环的性能差异? 现代编译器,(1)和(;;)之间没有性能差异。 是如何实现这些循环的技术分析在编译器中: perl: S-> 7 8 unstack v-> 4 -e语法ok 在GCC中,两者都循环到相同的汇编代码中,如下所示:。 globl t_时 t_时...
    编程 发布于2025-02-07
  • 如何使用FormData()处理多个文件上传?
    如何使用FormData()处理多个文件上传?
    )处理多个文件输入时,通常需要处理多个文件上传时,通常是必要的。可以将fd.append("fileToUpload[]", files[x]);方法用于此目的,允许您在单个请求中发送多个文件。 初始尝试 在JavaScript中,一种常见方法是:); 但是,此代码仅处理第一...
    编程 发布于2025-02-07
  • 为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    为什么使用固定定位时,为什么具有100%网格板柱的网格超越身体?
    网格超过身体,用100%grid-template-columns 问题:考虑以下CSS和HTML: position:fixed; grid-template-columns:40%60%; grid-gap:5px; 背景:#eee; 当位置未固定时,网格将正确显示。但是,当...
    编程 发布于2025-02-07
  • Java是否允许多种返回类型:仔细研究通用方法?
    Java是否允许多种返回类型:仔细研究通用方法?
    在java中的多个返回类型:一个误解介绍,其中foo是自定义类。该方法声明似乎拥有两种返回类型:列表和E。但是,情况确实如此吗?通用方法:拆开神秘 [方法仅具有单一的返回类型。相反,它采用机制,如钻石符号“ ”。分解方法签名: :本节定义了一个通用类型参数,E。它表示该方法接受了扩展foo类的任...
    编程 发布于2025-02-07
  • 如何使用PHP将斑点(图像)正确插入MySQL?
    如何使用PHP将斑点(图像)正确插入MySQL?
    在尝试将image存储在mysql数据库中时,您可能会遇到一个可能会遇到问题。本指南将提供成功存储您的图像数据的解决方案。 easudy values('$ this-> image_id','file_get_contents($ tmp_image)...
    编程 发布于2025-02-07
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-02-07
  • 如何将数据插入MySQL:相当于MS SQL的散装插入物?
    如何将数据插入MySQL:相当于MS SQL的散装插入物?
    在MySQL中插入:在数据库管理的领域中拆开其等效于MS SQL 的等价,有效数据加载是必不可少的。 Microsoft SQL Server拥有批量插入命令,用于迅速从文本文件中导入数据。同样,MySQL提供了一个类似的解决方案来完成此任务。 在MySQL中执行批量插入操作,使用的主要技术是负载...
    编程 发布于2025-02-07
  • 如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    如何使用char_length()在mySQL中按字符串长度对数据进行排序?
    [2使用内置的char_length()function。 char_length()和length() 此查询将从指定的表中检索所有行,并基于上升顺序对它们进行排序指定列的字符长度。带有更长字符串的行将出现在结果的底部。
    编程 发布于2025-02-07
  • 如何使用LOAD_FILE故障排除MySQL Blob加载问题?
    如何使用LOAD_FILE故障排除MySQL Blob加载问题?
    加载文件加载到mysql blobs中,带有load_file ,假设您会遇到问题,将文件加载到mysql blob中,专门使用load_file函数。如文档中概述的,该功能的功能需要在服务器上满足某些条件。这些条件包括:[在服务器主机文件对所有用户的访问性 文件大小以下下方的max_allowe...
    编程 发布于2025-02-07
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。 To resolve this issue and ensure scripts execute on subsequent page visits, Firefox...
    编程 发布于2025-02-07
  • 如何在Java列表中有效计算元素的发生?
    如何在Java列表中有效计算元素的发生?
    计数列表中的元素出现在列表 中,在java编程中,列举列表中列举元素出现的任务来自列表。为此,收集框架提供了全面的工具套件。在这种情况下,Batocurrences变量将保持值3,代表动物列表中的“ BAT”出现的数量。 &&& [此方法是简单的,可以得出准确的结果,使其成为计算列表中元素出现的理...
    编程 发布于2025-02-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3