React概述

React 学习概述

前言

React是由Facebook开发的一个用于构建用户界面的JavaScript库。它采用组件化的开发方式,使得构建复杂的应用变得更加简单和高效。React的核心特点包括声明式编程、组件化、虚拟DOM和单向数据流等。这些我下面都会一一介绍:

React的核心概念

声明式编程

React采用声明式编程范式,开发者只需描述UI在不同状态下的样子,React会负责更新和渲染组件。这种方式使得代码更加简洁易读,减少了手动操作DOM的复杂性。

JSX语法

JSX是一种JavaScript的语法扩展,允许在JavaScript代码中直接编写类似HTML的代码。JSX使得定义组件的结构更加直观。

组件(Components)

组件是React应用的基本构建块。每个组件都是一个独立的、可复用的UI单元,可以包含自己的状态和逻辑。组件可以是函数组件或类组件。组件化就是将整体UI拆分成多个小的、独立的部分,从而提高代码的可维护性和复用性。

虚拟DOM(Virtual DOM)

React使用虚拟DOM来提高性能。虚拟DOM是一个轻量级的JavaScript对象,表示真实DOM的副本。当组件的状态发生变化时,React会首先更新虚拟DOM,然后通过比较新旧虚拟DOM的差异,最小化地更新真实DOM。

单向数据流(One-way Data Flow)

React采用单向数据流的设计理念,数据从父组件传递到子组件。这样可以更容易地追踪数据的变化,提升应用的可维护性。

状态管理(State Management)

React组件可以拥有自己的状态(state),用于存储组件的动态数据。状态的变化会触发组件的重新渲染。对于复杂的应用,可以使用状态管理库(如Redux、MobX)来集中管理应用的状态。

React Hooks

React Hooks是React 16.8引入的一组函数,允许在函数组件中使用状态和其他React特性。常用的Hooks包括useState、useEffect、useContext等。

快速开始

React在2025年2月就表明正式弃用Create React App作为新应用的推荐工具,并建议现有应用迁移至框架(如Next.jsRemix等)或使用现代构建工具(如Viteparcel等)来创建React项目。所以在读一些旧文档的时候要注意这一点。下面我以Vite为例,介绍如何快速创建一个React项目:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

# 全局安装pnpm(可选),也可直接使用npm创建
npm install -g pnpm

# 创建一个新的Vite项目
pnpm create vite@latest my-react-app --template react
# 进入项目目录
cd my-react-app
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev

打开浏览器访问http://localhost:5173即可预览React应用。

React 组件命名规范

在React中,组件的命名通常遵循以下规范:

  1. 组件名称应以大写字母开头,以区分HTML标签和自定义组件。如果组件名称由多个单词组成,每个单词的首字母均应大写(驼峰命名法)。例如:MyComponentUserProfile
  2. 组件名称应具有描述性,能够清晰地表达组件的功能和用途。比如:ButtonHeaderFooter等。
  3. 组件文件名应与组件名称一致,使用驼峰命名法(CamelCase)。例如:MyComponent.jsxUserProfile.js

JSX 示例与规则

JSX 示例

1
2
3
4
5
6
7
import React from 'react';
const HelloWorld = () => {
	//() => 是箭头函数的写法,等价于 function HelloWorld() {}
	return <h1>Hello, World!</h1>;
}

export default HelloWorld;

这个简单的组件使用了JSX语法来定义一个返回<h1>元素的函数组件。其中import语句用于引入React库,HelloWorld组件返回一个包含文本"Hello, World!“的标题元素。export语句用于将组件导出,以便在其他文件中使用。default关键字表示这是该文件的默认导出。一个文件只能有一个默认导出。但可以有多个命名导出。关于这方面的内容在后续的文章中我会更详细地介绍。

JSX 规则

JSX只能返回一个根元素

在JSX中,组件必须返回一个单一的根元素。如果需要返回多个元素,可以使用一个父元素将它们包裹起来,或者使用React.Fragment(简写为<>…</>)来实现。例如:

1
2
3
4
5
6
return (
	<div>
		<h1>Hello, World!</h1>
		<p>Welcome to React!</p>
	</div>
);

或者使用Fragment:

1
2
3
4
5
6
return (
	<>
		<h1>Hello, World!</h1>
		<p>Welcome to React!</p>
	</>
);

标签必须闭合

在JSX中,所有的标签都必须闭合。对于自闭合标签(如<img><input>等),必须使用斜杠/>来闭合。例如:

1
<img src="image.jpg" alt="Image" />

对于只有开始标签的标签(如<ul><li>等),必须添加结束标签。例如:

1
2
3
4
<ul>
	<li>Item 1</li>
	<li>Item 2</li>
</ul>

使用大括号嵌入JavaScript表达式

在JSX中,可以使用大括号{}来嵌入JavaScript表达式。例如:

1
2
3
export default function Greeting({ name }) {
	return <h1>Hello, {name}!</h1>;
}

此处,{name}会被替换为变量name的值。

还可以用双大括号来嵌入对象字面量,例如:

1
2
3
export default function StyledDiv() {
	return <div style={{ color: 'red', fontSize: '20px' }}>Styled Text</div>;
}

使用驼峰命名法

在JSX中,属性名称应使用驼峰命名法(camelCase)。例如,使用className代替class,使用onClick代替onclick。例如:

1
<button className="btn" onClick={handleClick}>Click Me</button>

TSX 示例与规则

TSX 示例

1
2
3
4
5
6
import React from 'react';
const HelloWorld: React.FC = () => {
	return <h1>HelloWorld!</h1>;
}

export default HelloWorld;

这个示例展示了如何在React中使用TypeScript(TSX)来定义一个函数组件。与前面的JSX示例类似,这个组件返回一个包含文本"Hello, World!“的标题元素。不同之处在于,组件的类型被显式地声明为React.FC(Function Component),这有助于TypeScript进行类型检查和代码补全。React.FC是React提供的一个类型,用于定义函数组件的类型。后面我会对这个进行更详细的说明。TSX的语法规则与JSX类似,增加了类型注解和接口定义等TypeScript特性。就不在这里多说了。

TSX 规则

TSX的规则与JSX类似,但增加了类型注解和接口定义等TypeScript特性。以下是一些常见的TSX规则:

类型注解

在TSX中,可以为组件的props和state添加类型注解。例如:

1
2
3
4
5
6
7
interface GreetingProps {
	name: string;
}

const Greeting: React.FC<GreetingProps> = ({ name }) => {
	return <h1>Hello, {name}!</h1>;
}

使用接口定义props

可以使用接口(interface)来定义组件的props类型。例如:

1
2
3
4
5
6
7
8
interface ButtonProps {
	label: string;
	onClick: () => void;
}

const Button: React.FC<ButtonProps> = ({ label, onClick }) => {
	return <button onClick={onClick}>{label}</button>;
}

TSX的语法规则与JSX类似,增加了类型注解和接口定义等TypeScript特性。就不在这里多说了。

组件示例

React应用程序是由组件组成的,一个组件可以包含其他组件,以下是一个简单的React函数组件示例,实现了一个计数器功能:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import React, { useState } from 'react';

const Counter = () => {
	const [count, setCount] = useState(0);
	return (
		<div>
			<p>Count: {count}</p>
			<button onClick={() => setCount(count + 1)}>Increment</button>
		</div>
	);
};

export default Counter;

这个组件使用了useState Hook来管理计数器的状态。当点击按钮时,计数器的值会增加1,并触发组件重新渲染以显示最新的计数值。

注意事项: 组件中可以包含其他组件,但是不能在组件内部定义组件。组件应该在文件的顶层定义,以确保它们在每次渲染时保持一致。

Hooks 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import React, { useState, useEffect } from 'react';

const Timer = () => {
	const [seconds, setSeconds] = useState(0);

	useEffect(() => {
		const interval = setInterval(() => {
			setSeconds((prev) => prev + 1);
		}, 1000);
		return () => clearInterval(interval);
	}, []);

	return <div>Timer: {seconds} seconds</div>;
};

export default Timer;

这个组件使用了useEffect Hook来设置一个定时器,每秒钟更新一次计数器的值。当组件卸载时,清除定时器以避免内存泄漏。

结语

React是一个功能强大的JavaScript库,很多大厂都在使用React,它也是目前前端开发的主流框架,所以学习React是非常有必要的。因为React的知识体系庞大且较为复杂,本文只作为入门概述,建议结合官方文档和实际项目进行深入学习和实践,后面我也会一步步更新React的学习文档,不断深化理解。

参考资料

Licensed under CC BY-NC-SA 4.0