React的核心概念—组件

参考文章

组件的定义和使用

组件是 React 的核心概念之一。它们是构建用户界面(UI)的基础。

组件:UI 构成要素

在 Web 当中,HTML 允许使用其内置的标签集(如 <h1><li>)创建丰富的结构化文档:

<article><h1>我的第一个组件</h1><ol><li>组件:UI 构成要素</li><li>定义组件</li><li>使用组件</li></ol>
</article>

<article> 表示这篇文章,<h1> 表示文章的标题,<ol> 以有序列表的形式表示文章的(缩写的)目录。每一个侧边栏、头像、模态框、下拉框的背后都是像这样的(结合了用于样式的 CSS 和用于交互的 JavaScript的)标签——在 Web 上看到的每一个 UI 模块。

React 允许将标签、CSS 和 JavaScript 组合成自定义“组件”,即应用程序中可复用的 UI 元素。 上文中表示目录的代码可以改写成一个能够在每个页面中渲染的 <TableOfContents /> 组件。实际上,使用的依然是 <article><h1> 等相同的 HTML 标签。

就像使用 HTML 标签一样,可以组合、排序和嵌套组件来绘制整个页面。例如,下面的文档页面就是由 React 组件构成的:

<PageLayout><NavigationHeader><SearchBar /><Link to="/docs">文档</Link></NavigationHeader><Sidebar /><PageContent><TableOfContents /><DocumentationText /></PageContent>
</PageLayout>

随着项目的发展,会发现很多布局可以通过复用已经完成的组件来实现,从而加快开发进程。上文中提到的目录可以通过 <TableOfContents /> 组件添加到任意的画面中!也可以使用 React 开源社区分享的大量组件(例如 Chakra UI 和 Material UI)来快速启动项目。

定义组件

一直以来,创建网页时,Web 开发人员会用标签描述内容,然后通过 JavaScript 来增加交互。这种在 Web 上添加交互的方式能产生出色的效果。现在许多网站和全部应用都需要交互。React 最为重视交互性且使用了相同的处理方式:React 组件是一段可以 使用标签进行扩展 的 JavaScript 函数。如下所示:

export default function Profile() {return (<imgsrc="https://i.imgur.com/MK3eW3Am.jpg"alt="Katherine Johnson"/>)
}

以下是构建组件的方法:

第一步:导出组件

export default 前缀是一种 JavaScript 标准语法(非 React 的特性)。它允许导出一个文件中的主要函数以便以后可以从其他文件引入它。

第二步:定义函数

使用 function Profile() { } 定义名为 Profile 的 JavaScript 函数。

注意:React 组件是常规的 JavaScript 函数,但组件的名称必须以大写字母开头,否则它们将无法运行!

第三步:添加标签

这个组件返回一个带有 srcalt 属性的 <img /> 标签。<img /> 写得像 HTML,但实际上是 JavaScript!这种语法被称为 JSX,它允许在 JavaScript 中嵌入使用标签。

返回语句可以全写在一行上,如下面组件中所示:

return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;

但是,如果标签和 return 关键字不在同一行,则必须把它包裹在一对括号中,如下所示:

return (<div><img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" /></div>
);

注意:没有括号包裹的话,任何在 return 下一行(后面)的代码都 将被忽略!

使用组件

现在已经定义了 Profile 组件,可以在其他组件中使用它。例如,可以导出一个内部使用了多个 Profile 组件的 Gallery 组件:

function Profile() {return (<imgsrc="https://i.imgur.com/MK3eW3As.jpg"alt="Katherine Johnson"/>);
}export default function Gallery() {return (<section><h1>了不起的科学家</h1><Profile /><Profile /><Profile /></section>);
}

浏览器所看到的

注意下面两者的区别:

  • <section>是小写的,所以 React 知道指的是 HTML 标签。
  • <Profile /> 以大写 P 开头,所以 React 知道想要使用名为 Profile 的组件。

然而 Profile 包含更多的 HTML:<img />。这是浏览器最后所看到的:

<section><h1>了不起的科学家</h1><img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" /><img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" /><img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>

嵌套和组织组件

组件是常规的 JavaScript 函数,所以可以将多个组件保存在同一份文件中。当组件相对较小或彼此紧密相关时,这是一种省事的处理方式。如果这个文件变得臃肿,也可以随时将 Profile 移动到单独的文件中。

因为 Profile 组件在 Gallery 组件中渲染,甚至好几次!可以认为 Gallery 是一个 父组件, 将每个 Profile 渲染为一个“孩子”。这是 React 的神奇之处:可以只定义组件一次,然后按需多处和多次使用。

注意:组件可以渲染其他组件,但是 请不要嵌套他们的定义

export default function Gallery() {// 永远不要在组件中定义组件function Profile() {// ...}// ...
}

上面这段代码 非常慢,并且会导致 bug 产生。 因此,应该在顶层定义每个组件:

export default function Gallery() {// ...
}// 在顶层声明组件
function Profile() {// ...
}

当子组件需要使用父组件的数据时,需要 通过 props 的形式进行传递,而不是嵌套定义。

摘要

React关键点:

  • React 允许创建组件,应用程序的可复用 UI 元素。
  • 在 React 应用程序中,每一个 UI 模块都是一个组件。
  • React 是常规的 JavaScript 函数,除了:
    1. 它们的名字总是以大写字母开头。
    2. 它们返回 JSX 标签。

参考文章

组件的导入与导出

组件的神奇之处在于它们的可重用性:可以创建一个由其他组件构成的组件。但当嵌套了越来越多的组件时,则需要将它们拆分成不同的文件。这样可以使得查找文件更加容易,并且能在更多地方复用这些组件。

根组件文件

创建一个 Profile 组件,并且渲染在 Gallery 组件里。

// App.js
function Profile() {return (<imgsrc="https://i.imgur.com/MK3eW3As.jpg"alt="Katherine Johnson"/>);
}export default function Gallery() {return (<section><h1>了不起的科学家们</h1><Profile /><Profile /><Profile /></section>);
}

在此示例中,所有组件目前都定义在根组件 App.js 文件中,在 Create React App 中,应用应在 src/App.js 文件中定义。具体还需根据项目配置决定,有些根组件可能会声明在其他文件中。如果使用的框架基于文件进行路由,如 Next.js,那每个页面的根组件都会不一样。

导出和导入一个组件

如果将来需要在首页添加关于科学书籍的列表,亦或者需要将所有的资料信息移动到其他文件。这时将 Gallery 组件和 Profile 组件移出根组件文件会更加合理。这会使组件更加模块化,并且可在其他文件中复用。可以根据以下三个步骤对组件进行拆分:

  1. 创建 一个新的 JS 文件来存放该组件。
  2. 导出 该文件中的函数组件(可以使用 默认导出 或 具名导出)
  3. 在需要使用该组件的文件中 导入(可以根据相应的导出方式使用 默认导入 或 具名导入)。

这里将 Profile 组件和 Gallery 组件,从 App.js 文件中移动到了 Gallery.js 文件中。修改后,即可在 App.js 中导入 Gallery.js 中的 Gallery 组件:

// App.js
import Gallery from './Gallery.js';export default function App() {return (<Gallery />);
}
// Gallery.js
function Profile() {return (<imgsrc="https://i.imgur.com/QIrZWGIs.jpg"alt="Alan L. Hart"/>);
}export default function Gallery() {return (<section><h1>了不起的科学家们</h1><Profile /><Profile /><Profile /></section>);
}

该示例中需要注意的是,如何将组件拆分成两个文件:

  1. Gallery.js:
    • 定义了 Profile 组件,该组件仅在该文件内使用,没有被导出。
    • 使用 默认导出 的方式,将 Gallery 组件导出
  2. App.js:
    • 使用 默认导入 的方式,从 Gallery.js 中导入 Gallery 组件。
    • 使用 默认导出 的方式,将根组件 App 导出。

注意:引入过程中,可能会遇到一些文件并未添加 .js 文件后缀,如下所示:

import Gallery from './Gallery';

无论是 './Gallery.js' 还是 './Gallery',在 React 里都能正常使用,只是前者更符合 原生 ES 模块。

从同一文件中导出和导入多个组件

如果只想展示一个 Profile 组件,而不展示整个图集。也可以导出 Profile 组件。但 Gallery.js 中已包含 默认 导出,此时,不能定义 两个 默认导出。但可以将其在新文件中进行默认导出,或者将 Profile 进行 具名 导出。同一文件中,有且仅有一个默认导出,但可以有多个具名导出!

注意:为了减少在默认导出和具名导出之间的混淆,一些团队会选择只使用一种风格(默认或者具名),或者禁止在单个文件内混合使用。这因人而异,选择最适合的即可!

首先,用具名导出的方式,将 Profile 组件从 Gallery.js 导出(不使用 default 关键字):

export function Profile() {// ...
}

接着,用具名导入的方式,从 Gallery.js 文件中 导入 Profile 组件(用大括号):

import { Profile } from './Gallery.js';

最后,在 App 组件里 渲染 <Profile />

export default function App() {return <Profile />;
}

现在,Gallery.js 包含两个导出:一个是默认导出的 Gallery,另一个是具名导出的 ProfileApp.js 中均导入了这两个组件。尝试将 <Profile /> 改成 <Gallery />,回到示例中:

// App.js
import Gallery from './Gallery.js';
import { Profile } from './Gallery.js';export default function App() {return (<Profile />);
}
// Gallery.js
export function Profile() {return (<imgsrc="https://i.imgur.com/QIrZWGIs.jpg"alt="Alan L. Hart"/>);
}export default function Gallery() {return (<section><h1>了不起的科学家们</h1><Profile /><Profile /><Profile /></section>);
}

示例中混合使用了默认导出和具名导出:

  • Gallery.js
    • 使用 具名导出 的方式,将 Profile 组件导出,并取名为 Profile
    • 使用 默认导出 的方式,将 Gallery 组件导出。
  • App.js
    • 使用 具名导入 的方式,从 Gallery.js 中导入 Profile 组件,并取名为 Profile
    • 使用 默认导入 的方式,从 Gallery.js 中导入 Gallery 组件。
    • 使用 默认导出 的方式,将根组件 App 导出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/9441.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt - 控件和布局

文章目录 添加按钮 QPushButton自定义控件对象树坐标系 https://www.bilibili.com/video/BV1g4411H78N?p6 添加按钮 QPushButton 添加控件到窗口&#xff0c;需要添加内容到 mywidget.cpp #include "mywidget.h" #include <QPushButton> //按钮控件的头文件…

React 中 {} 的应用

列表渲染&#xff1a; 1.使用数组的 map 方法&#xff08;因为map 可以映射&#xff09; 2、列表要添加 key 属性&#xff0c;值要唯一 // 导入 // 用来获取 dom元素 import { createRoot } from "react-dom/client";// 内容 const contentArr [{ id: 1, name: &…

提高公文写作效率,可以采用模板和样例来辅助写作

采用模板和样例是提高公文写作效率的一种常见方法。 模板是指已经制作好的公文格式和结构模板&#xff0c;可以根据模板来组织和排版自己的文章&#xff0c;以减少排版时间和排版错误。常见的模板包括各类公文格式&#xff0c;例如通知、报告、请示等等。在使用模板的过程中&am…

java后端校验

Java 后端数据校验 一、概述 当我们想提供可靠的 API 接口&#xff0c;对参数的校验&#xff0c;以保证最终数据入库的正确性&#xff0c;是 必不可少 的活。比如下图就是 我们一个项目里 新增一个菜单校验 参数的函数&#xff0c;写了一大堆的 if else 进行校验&#xff0c;…

GPT4ALL私有化部署 01 | Python环境

进入以下链接&#xff1a; https://www.python.org/downloads/release/python-3100/ 滑动到底部 选择你系统对应的版本&#xff0c;如果你是win&#xff0c;那么大概率是win-64bit 有可能你会因为网络的问题导致下载不了&#xff0c;我提供了 链接 接着只需要打开 等待…

单例模式与构造器模式

单例模式 1、是什么 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a;创建型模式&#xff0c;提供了一种创建对象的最佳方式&#xff0c;这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被创建 在应用程序运…

Mac 快速生成树形项目结构目录

我这里使用的是通过包管理 Homebrew安装形式。没有安装的话可以自行搜索 Homebrew 安装方式 brew install tree直接到项目的根目录执行 tree 命令 tree 效果如下&#xff1a; or &#xff1a; tree -CfL 3效果如下&#xff1a;

opencv-24 图像几何变换03-仿射-cv2.warpAffine()

什么是仿射&#xff1f; 仿射变换是指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够 保持图像的平直性和平行性。平直性是指图像经过仿射变换后&#xff0c;直线仍然是直线&#xff1b;平行性是指 图像在完成仿射变换后&#xff0c;平行线仍然是平行线。…

基于LNMP配置WordPress建站时出现的问题汇总

这里写目录标题 wordpress上传文件报错问题描述原因分析&#xff1a;解决方案&#xff1a; wordpress裁剪图片报错问题描述原因分析&#xff1a;解决方案&#xff1a; wordpress上传文件报错 WP内部错误&#xff0c;在上传文件时发生了错误&#xff0c;显示权限不足无法保存 …

SQL注入--题目

联合查询注入&#xff1a; bugku-这是一个神奇的登录框 手工注入&#xff1a; 点吧&#xff0c;输入0’发现还是&#xff1a; 输入0" 发现报错&#xff1a; 确定可以注入&#xff0c;判断字段有多少个 0"order by 1,2,3# 发现&#xff1a; 说明有两列。 输入 0&qu…

Docker系列---【docker和docker容器设置开机启动】

docker和docker容器设置开机启动 1、设置docker开机启动 systemctl enable docker 2、设置容器自动重启 1)创建容器时设置 docker run -d --restartalways --name 设置容器名 使用的镜像 (上面命令 --name后面两个参数根据实际情况自行修改)# Docker 容器的重启策略如下&#…

【论文阅读22】Label prompt for multi-label text classification

论文相关 论文标题&#xff1a;Label prompt for multi-label text classification&#xff08;基于提示学习的多标签文本分类&#xff09; 发表时间&#xff1a;2023 领域&#xff1a;多标签文本分类 发表期刊&#xff1a;Applied Intelligence&#xff08;SCI二区&#xff0…

Linux 常用命令全拼

pwd&#xff1a;print work directoryps&#xff1a;process statusdf&#xff1a;disk freedu&#xff1a;disk usagecat&#xff1a;concatenate 连锁&#xff0c;连接insmod&#xff1a;install module 载入模块ln -s&#xff1a;link -soft 创建一个软链接&#xff0c;相当…

9 Linux实操篇-实用指令

9 Linux实操篇-实用指令 文章目录 9 Linux实操篇-实用指令9.1 指定和修改运行级别-init/systemctl9.2 找回root密码9.3 Linux的指令说明9.3 帮助类-man/help9.4 文件目录类-pwd/ls/cd/mkdir/...9.5 时间日期类-date/cal9.6 搜索查找类-find/locate/which/grep9.7 压缩和解压类-…

SpringBoot整合Elasticsearch

SpringBoot整合Elasticsearch SpringBoot整合Elasticsearch有以下几种方式&#xff1a; 使用官方的Elasticsearch Java客户端进行集成 通过添加Elasticsearch Java客户端的依赖&#xff0c;可以直接在Spring Boot应用中使用原生的Elasticsearch API进行操作。参考文档 使用Sp…

【Leetcode】50. Pow(x, n)

一、题目 1、题目描述 实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即, x n x^n xn )。 示例1: 输入:x 

数据库中的事务处理

MySQL的事务处理&#xff1a;只支持 lnnoDB 和BDB数据表类型 1.事务就是将一组SQL语句放在同一批次内去执行 2.如果一个SQL语句出错&#xff0c;则该批次内的所有SQL都将被取消执行 MySQL的事务实现方法一&#xff1a; select autocommit 查询当前事务提交模式 set a…

浅析交互中事实与价值信息的坍缩

在人机交互中&#xff0c;事实与价值的坍缩过程指的是在人与机器智能进行交互时&#xff0c;由于机器智能的回答和信息输出受到编程算法和数据训练的限制&#xff0c;导致人们难以准确区分机器智能提供的信息是基于客观事实还是主观价值观。 以下是人机交互中可能发生的事实与价…

机器学习深度学习——图像分类数据集

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——softmax回归&#xff08;下&#xff09; &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习…

JavaScript与TypeScript的区别

JavaScript和TypeScript是两种不同的编程语言&#xff0c;在一些方面有一些区别。 1. 类型系统&#xff1a;JavaScript是一种动态类型语言&#xff0c;变量的类型是在运行时确定的&#xff0c;并且可以随时更改。而TypeScript引入了静态类型系统&#xff0c;可以在编译时检查代…