My First Component
- Components: UI Building Blocks
- Defining a Component
- Using a Component
本文章基于React新文档Beta版,用于重新学习复习React知识,重新学习了解React的新特性。
组件(Components)是 React 的核心概念之一。它是构建用户界面(UI)的基石。React中一切皆为组件。
在HTML当中,由许多的标签组成一个网页,例如
My First Component
- Components: UI Building Blocks
- Defining a Component
- Using a Component
对于React的组件而言,则是由SS,JavaScript,HTML组合而成。组建完成后,可以作为应用程序可以重复使用的UI元素,其使用形式和HTML大致相同,通过排列和组合,嵌套来完成网页的构建。随着项目的进展,可以发现许多组件可以重复使用,大大减少了开发时间
Docs
React 将交互性放在第一位,同时仍然使用了与以前相同的技术:一个 React 组件就是一个 JavaScript 函数,并且你可以在函数中书写 markup
下面讲解如何构建一个组件:
export default前缀是一个 标准的 JavaScript 语法 (并非 React 专用)。改语法用于在文件中标记主函数(main function)以便将来在其它文件中导入(import)该函数。
通过function Profile() {}形式,你定义了一个名为Profile的 JavaScript 函数。
React 组件就是普通的 JavaScript 函数,但 函数名必须以大写字母开头,否则将无法正常使用!
该组件返回一个 标签(tag),并带有src和alt属性。从书写上看和 HTML 的标签是一样的,但实际上,它在底层是 JavaScript!这种语法被称为 JSX,它赋予你在 JavaScript 种书写 markup 的能力。
return 语句可以全部写在一行上,也可以不写在同一行,但要用圆括号括起来
//返回内容与return在同一行
return ;
//返回内容与return不在同一行,需要用圆括号括起来
return (
);
我们定义了Profile组件后,就可以将其嵌套在其他组件中,也可以进行反复渲染使用。在这里Gallery是父组件,Profile称为子组件
function Profile() {
return (
);
}
export default function Gallery() {
return (
Amazing scientists
);
}
组件的魔力在于可重用性:你可以创建由其它组件组成的新组件。但是,当你嵌套越来越多的组件时,将各个组件拆分到单独的文件中会更有意义。这让你能够轻松地查找文件,并在更多的地方重用组件。
刚才我们创建的Gallery和Profile都是在根组织文件中写的,在Create React App中,您的应用程序位于src/App.js
. 不过,根据您的设置,您的根组件可能位于另一个文件中。如果您使用具有基于文件的路由的框架,例如 Next.js,则每个页面的根组件都会有所不同。
我们不可能一直把所有的组件都堆在根组织文件中,这样不方便管理,而且放在其他文件中可以更加模块化和可重用。
可以通过三个步骤移动组件:
我们将干柴的Profile和Gallery移出App.js,在App.js中import它
//App.js
import Gallery from './Gallery.js';
export default function App() {
return (
);
}
//Gallery.js
function Profile() {
return (
);
}
export default function Gallery() {
return (
Amazing scientists
);
}
注意:此处App.js为 import Gallery from './Gallery'; 无论是'./Gallery.js'还是'./Gallery'都是可行的
注意这个例子现在是如何分解成两个组件文件的:
App
组件导出为默认导出。默认与命名导出
使用 JavaScript 导出值有两种主要方法:默认导出和命名导出。到目前为止,我们的示例只使用了默认导出。但是您可以在同一个文件中使用它们中的一个或两个。一个文件只能有一个默认导出,但它可以有任意多个命名导出。
您如何导出组件决定了您必须如何导入它。如果您尝试以与命名导出相同的方式导入默认导出,则会收到错误消息!此图表可以帮助您跟踪:
句法 出口声明 进口声明 默认 export default function Button() {}
import Button from './button.js';
命名 export function Button() {}
import { Button } from './button.js';
当您编写默认导入时,您可以在
import
. 例如,您可以import Banana from './button.js'
改为编写,它仍会为您提供相同的默认导出。相反,对于命名导入,名称必须在两边匹配。这就是为什么它们被称为命名进口!如果文件只导出一个组件,人们通常使用默认导出,如果它导出多个组件和值,则使用命名导出。无论您喜欢哪种编码风格,始终为您的组件函数和包含它们的文件提供有意义的名称。不鼓励使用没有名称的组件,例如
export default () => {}
,因为它们使调试更加困难。
如果您只想展示一个Profile而不是Gallery怎么办?您也可以导出Profile组件。但是Gallery.js已经有一个默认导出,你不能有两个默认导出。您可以使用默认导出创建一个新文件,也可以为Profile. 一个文件只能有一个默认导出,但它可以有多个命名导出!
为了减少默认导出和命名导出之间的潜在混淆,一些团队选择只坚持一种样式(默认或命名),或者避免将它们混合在一个文件中。这是一个偏好问题。做最适合你的事!
首先,使用命名导出(无关键字 )从Gallery.js导出Profile(不要写default导出)
export function Profile() {
// ...
}
然后将Profile从Gallery.js导入到App.js
import { Profile } from './Gallery.js';
最后,在App.js中将Profile渲染出来
export default function App() {
return ;
}
现在Gallery.js中拥有了两个导出,一个是其默认的defalut的Gallery导出,另一个则是 Profile的命名导出。在App.js中,两个组件都进行了导入
import Gallery from './Gallery.js';
import { Profile } from './Gallery.js';
export default function App() {
return (
<>
>
);
}
现在您正在混合使用默认导出和命名导出:
Gallery.js
:
Profile
组件导出为名为 的命名导出Profile
。Gallery
组件导出为默认导出。App.js
:
Profile
为名为Profile
from的命名导入Gallery.js
。Gallery
作为默认导入从导入Gallery.js
。App
组件导出为默认导出。JSX 是 JavaScript 的语法扩展,可让您在 JavaScript 文件中编写类似 HTML 的标记。尽管还有其他编写组件的方法,但大多数 React 开发人员更喜欢 JSX 的简洁性,并且大多数代码库都使用它。
Web 是基于 HTML、CSS 和 JavaScript 构建的。多年来,Web 开发人员将内容保存在 HTML 中,在 CSS 中进行设计,在 JavaScript 中保存逻辑——通常在单独的文件中!内容在 HTML 中标记,而页面的逻辑在 JavaScript 中单独存在:
但随着网络变得更具交互性,逻辑越来越决定内容。JavaScript负责HTML!这就是为什么在 React 中,渲染逻辑和标记一起存在于同一个地方——组件!
将按钮的呈现逻辑和标记保持在一起可确保它们在每次编辑时彼此保持同步。相反,不相关的细节,例如按钮的标记和侧边栏的标记,是相互隔离的,因此可以更安全地自行更改其中任何一个。
每个 React 组件都是一个 JavaScript 函数,其中可能包含一些 React 呈现到浏览器中的标记。React 组件使用称为 JSX 的语法扩展来表示该标记。JSX 看起来很像 HTML,但它更严格一些,可以显示动态信息。理解这一点的最好方法是将一些 HTML 标记转换为 JSX 标记。
假设您有一些(完全有效的)HTML:
Hedy Lamarr's Todos
- Invent new traffic lights
- Rehearse a movie scene
- Improve the spectrum technology
你想把它放到你的组件中:
export default function TodoList() {
return (
// ???
)
}
如果您按原样复制并粘贴它,它将不起作用:
这是因为 JSX 比 HTML 更严格并且规则更多!如果您阅读了上面的错误消息,它们将指导您修复标记,或者您可以按照下面的指南进行操作。
要从一个组件返回多个元素和标签,请用一个父标签包装它们。
例如,您可以使用 这个空标签称为React 片段。React Fragments 让您可以在浏览器 HTML 树中不留任何痕迹地对事物进行分组。 JSX 要求标签被显式关闭:像必须成为的自关闭标签,像这样的包装标签 JSX 变成了 JavaScript,用 JSX 编写的属性变成了 JavaScript 对象的键。在您自己的组件中,您通常希望将这些属性读入变量。但是 JavaScript 对变量名有限制。例如,它们的名称不能包含破折号或保留字如class. 这就是为什么在 React 中,许多 HTML 和 SVG 属性都是用 camelCase 编写的。例如,代替stroke-width您使用strokeWidth. 因为class是一个保留字,所以在 React 中你改用相应的 DOM 属性className命名: 可以使用转换器将现有的 HTML 和 SVG 转换为 JSX。转换器在实践中非常有用Hedy Lamarr's Todos
...
Hedy Lamarr's Todos
...
>
2.关闭所有标签
<>
>3. camelCase 几乎所有的东西!
使用 JSX 转换器