news 2026/2/16 4:17:51

react组件(1)---从入门到上手

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
react组件(1)---从入门到上手

组件是 React 的核心基石,也是 React 生态中最具代表性的设计思想。它将 UI 拆分为独立、可复用的单元,就像乐高积木一样,通过组合不同的组件可以构建出复杂的页面。从早期的类组件到如今的函数组件 + Hooks,React 组件的开发模式不断进化,变得更加简洁、灵活。本文将从组件本质、分类、创建、核心特性、通信、复用、性能优化等维度,全面解析 React 组件的使用方法与最佳实践,帮助你彻底掌握这一核心技能。

一、React 组件的本质:什么是组件?

1. 组件的定义

React 组件是独立的、可复用的 UI 单元,它接收输入(Props),处理内部逻辑(State/Hooks),最终返回用于描述 UI 的 JSX(或 React 元素)。简单来说,组件就是一个 “函数”:输入数据,输出 UI。

2. 组件的核心思想:模块化与复用

在传统的前端开发中,我们通常按页面划分代码,代码耦合度高,复用性差。而 React 的组件化思想解决了这一问题:

  • 单一职责:一个组件只负责完成一个特定的功能(比如一个按钮、一个列表、一个弹窗);
  • 可复用:组件可以在不同页面、不同项目中重复使用;
  • 可组合:组件可以嵌套、组合,形成更复杂的组件或页面;
  • 可维护:组件独立存在,修改一个组件不会影响其他组件,便于后期维护。

3. 组件的本质:函数或类

无论哪种类型的 React 组件,其本质都是JavaScript 函数或类

  • 函数组件:本质是一个普通的 JavaScript 函数,接收 props 参数,返回 JSX;
  • 类组件:本质是继承自React.Component的类,通过render方法返回 JSX。

举个最简单的例子,一个显示 “Hello React” 的组件:

// 函数组件(主流) const Hello = () => { return <h1>Hello React</h1>; }; // 类组件(旧版写法,现在极少使用) import React from 'react'; class HelloClass extends React.Component { render() { return <h1>Hello React</h1>; } }

二、React 组件的分类:不同类型的组件及适用场景

React 组件可以根据实现方式、职责、特性分为不同类型,了解这些分类有助于我们在开发中选择合适的组件类型。

1. 按实现方式划分:函数组件 vs 类组件

这是最核心的分类方式,也是 React 发展的重要分水岭。

特性函数组件(Function Component)类组件(Class Component)
语法复杂度简洁,普通 JS 函数繁琐,需要继承 React.Component,写 render 方法
状态管理依赖 Hooks(useState、useReducer)依赖 this.state 和 this.setState
生命周期依赖 Hooks(useEffect)有固定的生命周期方法(componentDidMount 等)
性能略优(无类实例化开销)略差(需要实例化类)
适用场景所有场景(React 16.8 + 推荐)老项目维护、特殊场景(如需要继承的组件)

注意:React 16.8 版本引入 Hooks 后,函数组件已经能够实现类组件的所有功能,目前函数组件 + Hooks是 React 开发的主流方式,类组件仅在老项目中存在。

2. 按职责划分:展示组件 vs 容器组件

这是一种基于 “关注点分离” 的分类方式,用于区分组件的功能职责。

展示组件(Presentational Component)
  • 职责:只负责 UI 的展示,不处理业务逻辑,也不管理状态;
  • 数据来源:通过 Props 接收外部传入的数据和回调函数;
  • 特点:纯函数式、可复用性高、无副作用。
// 展示组件:只渲染列表项,不处理数据逻辑 const TodoItem = ({ text, onDelete }) => { return ( <li> {text} <button onClick={onDelete}>删除</button> </li> ); };
容器组件(Container Component)
  • 职责:负责处理业务逻辑、管理状态、请求数据,不关心 UI 展示;
  • 数据来源:自身的 State 或外部状态管理库(Redux、Mobx);
  • 特点:通常不直接渲染 JSX,而是将数据和方法通过 Props 传递给展示组件。
// 容器组件:处理待办事项的逻辑,管理状态 import { useState } from 'react'; const TodoListContainer = () => { const [todos, setTodos] = useState(['学习React组件', '写博客']); const handleDelete = (index) => { setTodos(todos.filter((_, i) => i !== index)); }; return ( <ul> {todos.map((todo, index) => ( <TodoItem key={index} text={todo} onDelete={() => handleDelete(index)} /> ))} </ul> ); };

补充:随着 Hooks 的普及,这种分类方式逐渐淡化,因为我们可以通过自定义 Hooks 将业务逻辑抽离,让组件同时兼具展示和逻辑功能。

3. 其他常见分类

  • 纯组件(Pure Component):类组件中的React.PureComponent或函数组件中的React.memo,用于优化性能,避免不必要的重渲染;
  • 高阶组件(Higher-Order Component,HOC):一个接收组件并返回新组件的函数,用于复用组件逻辑;
  • 门户组件(Portal):用于将组件渲染到 DOM 树的其他位置,如弹窗、提示框;
  • 懒加载组件:通过React.lazySuspense实现的按需加载组件。

三、组件的创建与基础使用

本节将重点讲解函数组件的创建与使用(类组件仅作简单介绍),包括 Props 接收、默认值、类型校验等核心知识点。

1. 基础函数组件的创建与渲染

(1)创建函数组件

函数组件是一个普通的 JavaScript 函数,返回值为 JSX(或 null、false,表示不渲染任何内容)。

// 无参数的基础组件 const Button = () => { return <button>点击我</button>; }; // 箭头函数简写(无大括号时,return可省略) const Text = () => <p>这是一段文本</p>; // 普通函数写法(兼容旧版JS) function Title() { return <h1>这是标题</h1>; }
(2)渲染组件

组件创建完成后,可以像使用 HTML 标签一样在其他组件中渲染,注意组件名必须以大写字母开头(React 的约定,用于区分原生 HTML 标签)。

// 根组件 const App = () => { return ( <div className="app"> <Title /> <Text /> <Button /> </div> ); }; // 渲染到DOM import { createRoot } from 'react-dom/client'; const root = createRoot(document.getElementById('root')); root.render(<App />);

2. Props:组件的输入参数

Props(Properties 的缩写)是组件的输入参数,用于从父组件向子组件传递数据。Props 是只读的,子组件不能修改 Props(这是 React 的单向数据流原则)。

(1)接收与使用 Props
// 子组件:接收props const Greeting = (props) => { // props是一个对象,包含父组件传递的所有属性 return <h1>Hello, {props.name}!</h1>; }; // 父组件:传递props const App = () => { return ( <div> {/* 传递字符串属性 */} <Greeting name="React" /> {/* 传递非字符串属性(需用{}包裹) */} <Greeting age={18} /> {/* 传递布尔值 */} <Greeting isShow={true} /> {/* 传递函数 */} <Greeting onButtonClick={() => alert('点击了')} /> {/* 传递JSX元素(对应props.children) */} <Greeting> <p>这是子元素</p> </Greeting> </div> ); };
(2)Props 解构赋值

为了简化代码,通常使用解构赋值直接提取 Props 中的属性。

// 基础解构 const Greeting = ({ name, age }) => { return ( <div> <h1>Hello, {name}!</h1> <p>年龄:{age}</p> </div> ); }; // 解构+默认值 const Greeting = ({ name = '游客', age = 0 }) => { return ( <div> <h1>Hello, {name}!</h1> <p>年龄:{age}</p> </div> ); };
(3)默认 Props

除了使用解构赋值设置默认值,还可以通过defaultProps属性设置组件的默认 Props(适用于函数组件和类组件)。

const Greeting = ({ name, age }) => { return ( <div> <h1>Hello, {name}!</h1> <p>年龄:{age}</p> </div> ); }; // 设置默认Props Greeting.defaultProps = { name: '游客', age: 0 };
(4)Props 类型校验

为了提高代码的健壮性,我们可以使用prop-types库对 Props 的类型进行校验(React v15.5.0 后,PropTypes 从 React 核心库中移出,需单独安装)。

步骤 1:安装 prop-types

npm install prop-types --save # 或 yarn add prop-types

步骤 2:使用 PropTypes 进行类型校验

import PropTypes from 'prop-types'; const Greeting = ({ name, age, isShow, onButtonClick, children }) => { return ( <div> <h1>Hello, {name}!</h1> <p>年龄:{age}</p> {children} </div> ); }; // 类型校验 Greeting.propTypes = { // 字符串,必传 name: PropTypes.string.isRequired, // 数字(也可以是字符串) age: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), // 布尔值 isShow: PropTypes.bool, // 函数 onButtonClick: PropTypes.func, // 任意React节点 children: PropTypes.node }; // 默认Props Greeting.defaultProps = { name: '游客', age: 0, isShow: false };

3. 类组件的创建(仅作了解)

类组件需要继承React.Component,并实现render方法返回 JSX。

import React from 'react'; import PropTypes from 'prop-types'; class Greeting extends React.Component { // 默认Props static defaultProps = { name: '游客', age: 0 }; // 类型校验 static propTypes = { name: PropTypes.string.isRequired, age: PropTypes.number }; render() { const { name, age } = this.props; return ( <div> <h1>Hello, {name}!</h1> <p>年龄:{age}</p> </div> ); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/16 20:38:08

GPT-5.2正式发布!国内首发“喂饭级”使用教程

近段时间&#xff0c;谷歌凭借Gemini 3赢得了一大批用户&#xff0c;称得上火力全开。12月11日&#xff0c;OpenAI也正式发布了新版本GPT-5.2&#xff0c;全力应对Gemini 3。虽然版本号只加了0.1&#xff0c;但GPT-5.2在多个实用领域&#xff08;干活能力&#xff09;更强了&am…

作者头像 李华
网站建设 2026/2/16 6:15:54

Caddy:把 HTTPS 变成默认选项的现代 Web 服务器

Caddy 是什么&#xff1f; Caddy 是一个现代化的 Web 服务器、反向代理和自动 HTTPS 平台。如果只用一句话来形容 —— Caddy 是“把 HTTPS 当成默认行为”的 Web 服务器。 和 Nginx、Apache 不同&#xff0c;Caddy 从诞生之初就围绕一个核心理念设计&#xff1a;安全应该是默…

作者头像 李华
网站建设 2026/2/16 19:22:49

Q-learning 算法 —— 无模型(model-free)强化学习

眼里没有对纪念日的专属感言&#xff0c;只有对优质文章诞生的渴望&#xff01;&#xff01;&#xff01; 一、研究背景与意义二、Q-learning 的核心思想1. 状态-动作价值函数&#xff08;Q 函数&#xff09;2. 核心创新点三、Q-learning 的更新公式&#xff08;核心公式&#…

作者头像 李华
网站建设 2026/2/16 15:32:00

如何避免过拟合?EmotiVoice在小样本下的鲁棒性设计

如何避免过拟合&#xff1f;EmotiVoice在小样本下的鲁棒性设计 在语音合成技术迅速普及的今天&#xff0c;我们早已不再满足于“能说话”的机器。用户期待的是有情感、有个性、像真人一样的声音——无论是虚拟助手温柔地安慰你&#xff0c;还是游戏角色愤怒地呐喊&#xff0c;背…

作者头像 李华
网站建设 2026/2/16 23:56:02

JavaScript 动态网页开发核心问题及实现页面动态更新方法

动态网页开发是现代Web应用的核心&#xff0c;而JavaScript是实现这一能力的关键语言。它不再是简单的页面装饰工具&#xff0c;而是驱动复杂交互、数据处理和实时内容更新的引擎。掌握JavaScript动态开发&#xff0c;意味着你能构建出响应迅速、体验流畅的现代网站。本文将避开…

作者头像 李华
网站建设 2026/2/16 3:16:29

Python中append()方法的使用、原理及效率解析

在Python编程中&#xff0c;列表的append()方法是一个基础且高频使用的操作&#xff0c;用于在列表末尾添加新元素。它看似简单&#xff0c;却直接影响着代码的效率与可读性。许多开发者因其便利性而过度依赖&#xff0c;却忽略了其背后的原理和潜在的性能陷阱。理解append()的…

作者头像 李华