编写你的第一个组件
组件(Components)是 React 的核心概念之一。它是构建用户界面(UI)的基石,因此,对组件的学习成为你 React 旅程中完美的第一站!
You will learn
- 组件(component)是什么
- 组件在 React 应用程序中扮演着什么样的角色
- 如何编写你的第一个 React 组件
组件(Components):用户界面(UI)的构建块
在网站上,HTML 为我们提供了许多创建丰富的结构化文档的内置标签(tags),例如 <h1>
和 <li>
:
<article>
<h1>My First Component</h1>
<ol>
<li>Components: UI Building Blocks</li>
<li>Defining a Component</li>
<li>Using a Component</li>
</ol>
</article>
上述代码表示的是一篇用 <article>
标记的文章,包括标题 <h1>
,以及利用有序列表 <ol>
列出的目录。像这样的 markup,并结合 CSS 用于描绘样式以及 JavaScript 增加交互能力,构成了所有网站 UI 上的侧边栏(sidebar)、头像(avatar)、模态框(modal)、下拉菜单(dropdown)等组成部分。
React 赋予你将标记(markup)、CSS 和 JavaScript 组合成自定义的 “组件(components)” 的能力,也就是 针对你的应用程序的可重用 UI 元素。 你在上面看到的目录代码可以变成一个 <TableOfContents />
组件,并渲染到每个页面上。其底层,仍然是使用的相同的 HTML 标签(tags),例如 <article>
、<h1>
等。
就像 HTML 的标签(tags)一样,你可以组合、排序以及嵌套组件来组成整个页面。例如,你正在阅读的这份文档就是由以下这些 React 组件组成的:
<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">Docs</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>
随着项目的发展,你会注意到许多设计都可以通过重用你已经编写的组件来完成,从而提升开发速度。我们上面示例中的目录可以在任何使用了 <TableOfContents />
组件的页面上渲染!你甚至可以使用 React 开源社区中(例如 Chakra UI 和 Material UI)所共享的数千个组件来快速启动你的项目。
定义组件
传统意义上,在创建网页时,web 开发人员会通过对内容做标记,然后添加一些 JavaScript 代码实现交互功能。当网站上的这种交互是“有比没有强”时,这种方式很不错。但是,现在许多网站和所有的应用程序都需要添加交互能力,这种方式就很落后了。React 将交互性放在第一位,同时仍然使用了与以前相同的技术:一个 React 组件就是一个 JavaScript 函数,并且你可以在函数中 书写 markup。以下就是一个示例(你可以编辑):
export default function Profile() { return ( <img src="https://i.imgur.com/MK3eW3Am.jpg" alt="Katherine Johnson" /> ) }
下面讲解如何构建一个组件:
第一步:导出(export)组件
export default
前缀时一个 标准的 JavaScript 语法 (并非 React 专用)。改语法用于在文件中标记主函数(main function)以便将来在其它文件中导入(import)该函数。(更多相关信息请参考 导入(import)和导出(export)组件 章节!)
第二部:定义函数
通过 function Profile() { }
形式,你定义了一个名为 Profile
的 JavaScript 函数。
Pitfall
React 组件就是普通的 JavaScript 函数,但 函数名必须以大写字母开头,否则将无法正常使用!
第三步:添加 markup
该组件返回一个 <img />
标签(tag),并带有 src
和 alt
属性。<img />
从书写上看和 HTML 的标签是一样的,但实际上,它在底层是 JavaScript!这种语法被称为 JSX,它赋予你在 JavaScript 种书写 markup 的能力。
return 语句可以全部写在一行上,如下面组件所示:
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>
);
Pitfall
如果不写圆括号,return
后面的所有代码行 将被忽略!
使用组件
现在已经定义了 Profile
组件,你可以将其嵌套到其它组件中了。例如,你可以导出(export)一个包含多个 Profile
组件的 Gallery
组件:
function Profile() { return ( <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" /> ); } export default function Gallery() { return ( <section> <h1>Amazing scientists</h1> <Profile /> <Profile /> <Profile /> </section> ); }
浏览器看到的是什么
请注意
<section>
是全部字母小写的,React 将其看作是 HTML 标签。<Profile />
以大写字母P
开头,React 将其看作是对我们的Profile
组件的引用。
并且,Profile
中包含了更多的 HTML 标签:<img />
。最后,浏览器看到的将是:
<section>
<h1>Amazing scientists</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>
组件的嵌套和组织结构
组件(Components)就是普通的 JavaScript 函数,因此可以在同一个文件中定义多个组件。当组件相对较小或彼此紧密相关时,放在一起就非常方便。但是,如果文件变得很臃肿了,你就需要将 Profile
组件放到单独的文件中了。你将在 导入(import)与导出(export)组件 章节了解到如何操作。
由于 Profile
组件在 Gallery
组件中渲染,甚至渲染了多次,我们可以说 Gallery
是一个 父组件(parent component), 将每个 Profile
渲染为一个 “子组件(child component)“。这是 React 的神奇之处:你可以定义一个组件,然后在任意多个位置使用多次。
Deep Dive
Components All the Way Down
Recap
你刚刚对 React 有了一些初步的认识。接下来我们回顾一下要点。
React 赋予你创建 可重用的 UI 元素 的能力。
在 React 应用程序中,每个 UI 部分都是一个组件。
React 组件是普通的 JavaScript 函数,并且:
- 函数名的首字母大写。
- 返回值是 JSX markup。
Try out some challenges
Challenge 1 of 4: 导出(export)组件
下面这个代码沙盒并不能运行,因为没有导出(export)根组件:
function Profile() { return ( <img src="https://i.imgur.com/lICfvbD.jpg" alt="Aklilu Lemma" /> ); }
再查看答案之前,请尝试自己修复它!