Components are one of the core concepts of React. They are the foundation upon which you build user interfaces (UI), which makes them the perfect place to start your React journey! 组件 是 React 的核心概念之一。它们是构建用户界面(UI)的基础,是你开始 React 之旅的最佳起点!
你将会学习到
- What a component is
- 什么是组件
- What role components play in a React application
- 组件在 React 应用中扮演的角色
- How to write your first React component
- 如何编写你的第一个 React 组件
组件:UI 构成要素 | Components: UI building blocks
On the Web, HTML lets us create rich structured documents with its built-in set of tags like <h1>
and <li>
:
在 Web 当中,HTML 允许我们使用其内置的标签集(如 <h1>
和 <li>
)创建丰富的结构化文档:
<article>
<h1>我的第一个组件</h1>
<ol>
<li>组件:UI 构成要素</li>
<li>定义组件</li>
<li>使用组件</li>
</ol>
</article>
This markup represents this article <article>
, its heading <h1>
, and an (abbreviated) table of contents as an ordered list <ol>
. Markup like this, combined with CSS for style, and JavaScript for interactivity, lies behind every sidebar, avatar, modal, dropdown—every piece of UI you see on the Web.
<article>
表示这篇文章,<h1>
表示文章的标题,<ol>
以有序列表的形式表示文章的(缩写的)目录。每一个侧边栏、头像、模态框、下拉框的背后是都是像这样的(结合了用于样式的 CSS 和用于交互的 JavaScript 的)标签——你在 Web 上看到的每一个 UI 模块。
React lets you combine your markup, CSS, and JavaScript into custom “components”, reusable UI elements for your app. The table of contents code you saw above could be turned into a <TableOfContents />
component you could render on every page. Under the hood, it still uses the same HTML tags like <article>
, <h1>
, etc.
React 允许你将标签、CSS 和 JavaScript 组合成自定义“组件”,即 应用程序中可复用的 UI 元素。上文中表示目录的代码可以改写成一个能够在每个页面中渲染的 <TableOfContents />
组件。实际上,使用的依然是 <article>
、<h1>
等相同的 HTML 标签。
Just like with HTML tags, you can compose, order and nest components to design whole pages. For example, the documentation page you’re reading is made out of React components: 就像使用 HTML 标签一样,你可以组合、排序和嵌套组件来绘制整个页面。例如,你正在阅读的文档页面就是由 React 组件构成的:
<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">文档</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>
As your project grows, you will notice that many of your designs can be composed by reusing components you already wrote, speeding up your development. Our table of contents above could be added to any screen with <TableOfContents />
! You can even jumpstart your project with the thousands of components shared by the React open source community like Chakra UI and Material UI.
随着项目的发展,你会发现很多布局可以通过复用已经完成的组件来实现,从而加快开发进程。上文中提到的目录可以通过 <TableOfContents />
组件添加到任意的画面中!你也可以使用 React 开源社区分享的大量组件(例如 Chakra UI 和 Material UI)来快速启动项目。
定义组件 | Defining a component
Traditionally when creating web pages, web developers marked up their content and then added interaction by sprinkling on some JavaScript. This worked great when interaction was a nice-to-have on the web. Now it is expected for many sites and all apps. React puts interactivity first while still using the same technology: a React component is a JavaScript function that you can sprinkle with markup. Here’s what that looks like (you can edit the example below): 一直以来,创建网页时,Web 开发人员会用标签描述内容,然后通过 JavaScript 来增加交互。这种在 Web 上添加交互的方式能产生出色的效果。现在许多网站和全部应用都需要交互。React 最为重视交互性且使用了相同的处理方式:React 组件是一段可以 使用标签进行扩展 的 JavaScript 函数。如下所示(你可以编辑下面的示例):
export default function Profile() { return ( <img src="https://i.imgur.com/MK3eW3Am.jpg" alt="Katherine Johnson" /> ) }
And here’s how to build a component: 以下是构建组件的方法:
第一步:导出组件 | Step 1: Export the component
The export default
prefix is a standard JavaScript syntax (not specific to React). It lets you mark the main function in a file so that you can later import it from other files. (More on importing in Importing and Exporting Components!)
export default
前缀是一种 JavaScript 标准语法(非 React 的特性)。它允许你导出一个文件中的主要函数以便你以后可以从其他文件引入它。欲了解更多关于导入的内容,请参阅 组件的导入与导出 章节!
第二步:定义函数 | Step 2: Define the function
With function Profile() { }
you define a JavaScript function with the name Profile
.
使用 function Profile() { }
定义名为 Profile
的 JavaScript 函数。
第三步:添加标签 | Step 3: Add markup
The component returns an <img />
tag with src
and alt
attributes. <img />
is written like HTML, but it is actually JavaScript under the hood! This syntax is called JSX, and it lets you embed markup inside JavaScript.
这个组件返回一个带有 src
和 alt
属性的 <img />
标签。<img />
写得像 HTML,但实际上是 JavaScript!这种语法被称为 JSX,它允许你在 JavaScript 中嵌入标签。
Return statements can be written all on one line, as in this component: 返回语句可以全写在一行上,如下面组件中所示:
return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;
But if your markup isn’t all on the same line as the return
keyword, you must wrap it in a pair of parentheses:
但是,如果你的标签和 return
关键字不在同一行,则必须把它包裹在一对括号中,如下所示:
return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>
);
使用组件 | Using a component
Now that you’ve defined your Profile
component, you can nest it inside other components. For example, you can export a Gallery
component that uses multiple Profile
components:
现在你已经定义了 Profile
组件,你可以在其他组件中使用它。例如,你可以导出一个内部使用了多个 Profile
组件的 Gallery
组件:
function Profile() { return ( <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" /> ); } export default function Gallery() { return ( <section> <h1>了不起的科学家</h1> <Profile /> <Profile /> <Profile /> </section> ); }
浏览器所看到的 | What the browser sees
Notice the difference in casing: 注意下面两者的区别:
<section>
is lowercase, so React knows we refer to an HTML tag.<section>
是小写的,所以 React 知道我们指的是 HTML 标签。<Profile />
starts with a capitalP
, so React knows that we want to use our component calledProfile
.<Profile />
以大写P
开头,所以 React 知道我们想要使用名为Profile
的组件。
And Profile
contains even more HTML: <img />
. In the end, this is what the browser sees:
然而 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>
Nesting and organizing components | 嵌套和组织组件
Components are regular JavaScript functions, so you can keep multiple components in the same file. This is convenient when components are relatively small or tightly related to each other. If this file gets crowded, you can always move Profile
to a separate file. You will learn how to do this shortly on the page about imports.
组件是常规的 JavaScript 函数,所以你可以将多个组件保存在同一份文件中。当组件相对较小或彼此紧密相关时,这是一种省事的处理方式。如果这个文件变得臃肿,你也可以随时将 Profile
移动到单独的文件中。你可以立即在 关于引入的页面 中学习如何做到这些。
Because the Profile
components are rendered inside Gallery
—even several times!—we can say that Gallery
is a parent component, rendering each Profile
as a “child”. This is part of the magic of React: you can define a component once, and then use it in as many places and as many times as you like.
因为 Profile
组件在 Gallery
组件中渲染——甚至好几次!——我们可以认为 Gallery
是一个 父组件,将每个 Profile
渲染为一个“孩子”。这是 React 的神奇之处:你可以只定义组件一次,然后按需多处和多次使用。
深入探讨
Your React application begins at a “root” component. Usually, it is created automatically when you start a new project. For example, if you use CodeSandbox or if you use the framework Next.js, the root component is defined in pages/index.js
. In these examples, you’ve been exporting root components.
你的 React 应用程序从“根”组件开始。通常,它会在启动新项目时自动创建。例如,如果你使用 CodeSandbox,根组件定义在 src/App.js
中。如果使用 Next.js 框架,根组件定义在 pages/index.js
中。在这些示例中,一直有导出根组件。
Most React apps use components all the way down. This means that you won’t only use components for reusable pieces like buttons, but also for larger pieces like sidebars, lists, and ultimately, complete pages! Components are a handy way to organize UI code and markup, even if some of them are only used once. 大多数 React 应用程序只有组件。这意味着你不仅可以将组件用于可复用的部分,例如按钮,还可以用于较大块的部分,例如侧边栏、列表以及最终的完整页面!组件是组织 UI 代码和标签的一种快捷方式,即使其中一些组件只使用了一次。
React-based frameworks take this a step further. Instead of using an empty HTML file and letting React “take over” managing the page with JavaScript, they also generate the HTML automatically from your React components. This allows your app to show some content before the JavaScript code loads. 像 Next.js 这样的框架会做更多事情。与使用一个空白的 HTML 页面并让 React 使用 JavaScript “接手”管理页面不同,框架还会根据你的 React 组件自动生成 HTML。这使你的应用程序在加载 JavaScript 代码之前能够展示一些内容。
Still, many websites only use React to add interactivity to existing HTML pages. They have many root components instead of a single one for the entire page. You can use as much—or as little—React as you need. 尽管如此,许多网站仅使用 React 来 添加“交互性”。它们有很多根组件,而不是整个页面的单个组件。你可以根据需要尽可能多或尽可能少地使用 React。
摘要
You’ve just gotten your first taste of React! Let’s recap some key points. 你刚刚第一次体验 React!让我们回顾一些关键点。
-
React lets you create components, reusable UI elements for your app.
-
React 允许你创建组件,应用程序的可复用 UI 元素。
-
In a React app, every piece of UI is a component.
-
在 React 应用程序中,每一个 UI 模块都是一个组件。
-
React components are regular JavaScript functions except:
-
React 是常规的 JavaScript 函数,除了:
- Their names always begin with a capital letter.
- 它们的名字总是以大写字母开头。
- They return JSX markup.
- 它们返回 JSX 标签。
第 1 个挑战 共 4 个挑战: 导出组件 | Export the component
This sandbox doesn’t work because the root component is not exported: 这个沙箱不起作用,因为根组件没有导出:
function Profile() { return ( <img src="https://i.imgur.com/lICfvbD.jpg" alt="Aklilu Lemma" /> ); }
Try to fix it yourself before looking at the solution! 看答案之前先尝试自己修复它!