ReactJS - 组件



React 组件是 React 应用程序的构建块。在本章中,让我们学习如何创建一个新的 React 组件以及 React 组件的特性。

React 组件表示网页中的一小块用户界面。React 组件的主要工作是渲染其用户界面,并在其内部状态发生变化时更新它。除了呈现 UI 之外,它还管理属于其用户界面的事件。总而言之,React 组件提供了以下功能。

  • 用户界面的初始呈现。
  • 事件的管理和处理。
  • 每当内部状态发生更改时更新用户界面。

React 组件使用三个概念来实现这些特性 -

  • 属性 − 使组件能够接收输入。
  • 事件 − 使组件能够管理 DOM 事件和最终用户交互。
  • 状态 - 使组件保持有状态。有状态组件根据其状态更新其 UI。

React 中有两种类型的组件。他们是 -

  • 功能组件
  • 类组件

功能组件

函数组件从字面上定义为 JavaScript 函数。这个 React 组件接受单个对象参数并返回一个 React 元素。请注意,React 中的元素不是组件,而是一个组件由多个元素组成。以下是 React 中函数组件的语法:


function function_name(argument_name) {
	 	function_body;
}

类组件

同样,类组件是由多个函数组成的基本类。React 的所有类组件都是 React.Component 类的子类,因此,类组件必须始终扩展它。以下是基本语法 -


class class_name extends React.Component {
	 render() {
	 	 return <h1>Hello, {this.props.name}</h1>;
	 }
}

让我们在接下来的章节中一一学习所有概念。

创建 React 组件

React 库有两种组件类型。这些类型根据其创建方式进行分类。

  • 函数组件 - 使用普通的JavaScript函数。
  • ES6 类组件 − 使用 ES6 类。

函数和类组件之间的核心区别是 :

  • 功能组件本质上是非常小的。它唯一的要求是返回一个 React 元素。

function Hello() {	
	 	return '<div>Hello</div>'	
}

使用 ES6 类组件可以完成相同的功能,只需很少的额外编码。


class ExpenseEntryItem extends React.Component { 	 	 	 		
	 	render() {	
	 	 	 return (	
	 	 	 	 	<div>Hello</div>	
	 	 	 );	
	 	}
}
  • 类组件支持开箱即用的状态管理,而函数组件不支持状态管理。但是,React 为函数组件提供了一个钩子 useState() 来维护其状态。
  • 类组件具有生命周期,并通过专用的回调 API 访问每个生命周期事件。功能组件没有生命周期。同样,React 为函数组件提供了一个钩子 useEffect() 来访问组件的不同阶段。

创建类组件

让我们创建一个新的 React 组件(在我们的费用管理器应用程序中),ExpenseEntryItem 来展示费用分录项。费用分录项目由名称、金额、日期和类别组成。费用分录项的对象表示为 -


{	
	 	'name': 'Mango juice',	
	 	'amount': 30.00,	
	 	'spend_date': '2020-10-10'	
	 	'category': 'Food',	
}

在您最喜欢的编辑器中打开费用管理器应用程序。

接下来,创建一个文件,ExpenseEntryItem.css src/components 文件夹下来设置我们的组件样式。

接下来,通过扩展 React.Component 创建一个文件,ExpenseEntryItem.js src/components 文件夹下。


import React from 'react';	
import './ExpenseEntryItem.css';	
class ExpenseEntryItem extends React.Component {	
}

接下来,在 ExpenseEntryItem 类中创建一个方法呈现。


class ExpenseEntryItem extends React.Component {	
	 	render() {	
	 	}	
}

接下来,使用 JSX 创建用户界面,并从 render 方法返回它。


class ExpenseEntryItem extends React.Component {
	 	render() {
	 	 	 return (
	 	 	 	 	<div>
	 	 	 	 	 	 <div><b>Item:</b> <em>Mango Juice</em></div>
	 	 	 	 	 	 <div><b>Amount:</b> <em>30.00</em></div>
	 	 	 	 	 	 <div><b>Spend Date:</b> <em>2020-10-10</em></div>
	 	 	 	 	 	 <div><b>Category:</b> <em>Food</em></div>
	 	 	 	 	</div>
	 	 	 );
	 	}
}

接下来,将组件指定为默认导出类。


import React from 'react';
import './ExpenseEntryItem.css';

class ExpenseEntryItem extends React.Component {
	 	render() {
	 	 	 return (
	 	 	 	 	<div>
	 	 	 	 	 	 <div><b>Item:</b> <em>Mango Juice</em></div>
	 	 	 	 	 	 <div><b>Amount:</b> <em>30.00</em></div>
	 	 	 	 	 	 <div><b>Spend Date:</b> <em>2020-10-10</em></div>
	 	 	 	 	 	 <div><b>Category:</b> <em>Food</em></div>
	 	 	 	 	</div>
	 	 	 );
	 	}
}
export default ExpenseEntryItem;

现在,我们成功创建了第一个 React 组件。让我们在 index.js中使用新创建的组件。


import React from 'react';
import ReactDOM from 'react-dom';
import ExpenseEntryItem from './components/ExpenseEntryItem'

ReactDOM.render(
	 	<React.StrictMode>
	 	 	 <ExpenseEntryItem />
	 	</React.StrictMode>,
	 	document.getElementById('root')
);

可以使用CDN在网页中完成相同的功能,如下所示 -


<!DOCTYPE html>
<html>
	 	<head>
	 	 	 <meta charset="UTF-8" />
	 	 	 <title>React application :: ExpenseEntryItem component</title>
	 	</head>
	 	<body>
	 	 	 <div id="react-app"></div>
	 	 	 	
	 	 	 <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
	 	 	 <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
	 	 	 <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
	 	 	 <script type="text/babel">
	 	 	 	 	class ExpenseEntryItem extends React.Component {
	 	 	 	 	 	 render() {
	 	 	 	 	 	 	 	return (
	 	 	 	 	 	 	 	 	 <div>
	 	 	 	 	 	 	 	 	 	 	<div><b>Item:</b> <em>Mango Juice</em></div>
	 	 	 	 	 	 	 	 	 	 	<div><b>Amount:</b> <em>30.00</em></div>
	 	 	 	 	 	 	 	 	 	 	<div><b>Spend Date:</b> <em>2020-10-10</em></div>
	 	 	 	 	 	 	 	 	 	 	<div><b>Category:</b> <em>Food</em></div>
	 	 	 	 	 	 	 	 	 </div>
	 	 	 	 	 	 	 	);
	 	 	 	 	 	 }
	 	 	 	 	}
	 	 	 	 	ReactDOM.render(
	 	 	 	 	 	 <ExpenseEntryItem />,
	 	 	 	 	 	 document.getElementById('react-app') );
	 	 	 </script>
	 	</body>
</html>

接下来,使用 npm 命令为应用程序提供服务。

npm start

输出

接下来,打开浏览器并在地址栏中输入 http://localhost:3000,然后按回车键。

Item: Mango Juice
Amount: 30.00
Spend Date: 2020-10-10
Category: Food

创建函数组件

React 组件也可以使用普通的 JavaScript 函数创建,但功能有限。基于函数的 React 组件不支持状态管理和其他高级功能。它可用于快速创建简单的组件。

上述 ExpenseEntryItem 可以按照下面指定的函数重写 -


function ExpenseEntryItem() {
	 	return (
	 	 	 <div>
	 	 	 	 	<div><b>Item:</b> <em>Mango Juice</em></div>
	 	 	 	 	<div><b>Amount:</b> <em>30.00</em></div>
	 	 	 	 	<div><b>Spend Date:</b> <em>2020-10-10</em></div>
	 	 	 	 	<div><b>Category:</b> <em>Food</em></div>
	 	 	 </div>
	 	);
}

在这里,我们只包含了渲染功能,创建一个简单的 React 组件就足够了。

拆分组件

即使据说 JavaScript 更易于执行,但很多时候由于相对简单的项目存在大量类或依赖项,代码会变得复杂。随着代码的增加,浏览器中的加载时间会变得更长。结果,降低了其性能的效率。这是可以使用代码拆分的地方。代码拆分用于将组件或捆绑包划分为更小的块以提高性能。

代码拆分只会加载浏览器当前需要的组件。此过程称为延迟加载。这将大大提高应用程序的性能。人们必须注意,我们并不是要用它来减少代码量,而只是试图通过加载用户可能永远不需要的组件来减轻浏览器的负担。让我们看一个示例代码。

我们首先看一下示例应用程序的捆绑代码,以执行任何操作。


// file name = app.js
import { sub } from './math.js';

console.log(sub(23, 14));
// file name = math.js
export function sub(a, b) {
	 return a - b;
}

上面应用程序的 Bundle 将如下所示 -


function sub(a, b) {
	 return a - b;
}
console.log(sub(23, 14));

现在,在应用程序中引入代码拆分的最佳方法是使用 dynamic import()。


// Before code-splitting
import { sub } from './math';

console.log(add(23, 14));

// After code-splitting
import("./math").then(math => {
	 console.log(math.sub(23, 14));
});

当使用此语法时(在像 Webpack 这样的捆绑包中),代码拆分将自动开始。但是,如果您正在创建 React App,则已经为您配置了代码拆分,您可以立即开始使用它。