构建UI:组件
由具有独立UI片段的组件构建,这种组件可以当成是是程序中可以复用的UI元素。这种可复用UI组件是react的一大特点。
组件本质:是可以添加标签的JavaScript函数,以及可以用CSS为其添加样式。
拿到一个需要构建的片段,可以用划分组件的方式去思考,如何通过一个个的组件构建页面。
例如:
function Profile() {
return (
<img
src="https://i.imgur.com/MK3eW3As.jpg"
alt="Katherine Johnson"
/>
);
}
export default function Gallery() {
return (
<section>
<Profile />
<Profile />
<Profile />
</section>
);
}
如上三张图片,分别为三个组件。构成了所要创建的页面。
构建组件的方法
如上所述,react的组件是可以添加标签的JavaScript函数,这是JSX语法。
- 第一步,先定义函数。
function Profile() {
}
!提示:虽然是定义函数,但注意定义的是React组件,组件名称必须用大写字母开头,否则无法运行。
- 第二步:在函数内添加标签,用return返回。
return ( <img src="转存失败,建议直接上传图片文件 https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson转存失败,建议直接上传图片文件">
);
注意写法:如果标签和return关键字不在同一行,则必须包裹在一对括号中,因为return下一行的代码会被忽略。在同一行可以不写括号。
- 第三步:导出组件 export default前缀是一种JavaScript标准语法(非React本身特性),导出文件主要函数,其他文件便可引用它。
function Profile() {
return (
<img
src="https://i.imgur.com/MK3eW3As.jpg"
alt="Katherine Johnson"
/>
);
}
export default function Gallery() {
return (
<section>
<Profile />
<Profile />
<Profile />
</section>
);
}
注意:虽然多个组件可以保存在同一份文件中,但是不要嵌套定义组件。
export default function Forward() {
// 错误,不要在组件中定义组件
function Inner() {
}
}
导入和导出一个组件步骤:
1.创建一个新的JS文件,后缀名是.js
2.导出文件中的函数组件(默认导出或具名导出)
3.需要使用函数组件的时候导入(默认导入或具名导入)
举例:
import imp from './imp.js';
export default function App() {
return (
<Gallery />
);
}
function Profile() {
return (
<img
src="https://i.imgur.com/QIrZWGIs.jpg"
alt="Alan L. Hart"
/>
);
}
export default function Gallery() {
return (
<section>
<h1>了不起的科学家们</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
注意:在imp.js文件中使用的是默认导出,在app.js中使用的是默认导入,导入imp.js文件。import imp from './imp.js';和import imp from './imp';两种写法均可,前者更符合原生ES模块。
具名导出和默认导出的区别如下显示:
语法 导出语句 导入语句 默认 export default function Button() {} import Button from >'./Button.js' 具名 export function Button() {} import {Button} from './Button.js' !一个文件里有且仅有一个默认导出,可以有任意多个具名导出。
JSX语法规则
- 只能返回一个根元素
需要一个父标签包裹组件中的标签,父标签可以是盒子标签,如<div></div>,也可以是空的<>和</>. 这个空的标签被叫做Fragment。React Fragment允许将自元素分组,而不会在HTML结构中添加额外节点。
<>
<h1>待办事项<h1/>
<ul><ul/>
</>
为什么只能返回一个父元素? JSX语法在运行时,要被转化为JS对象,一个函数不能返回多个对象,除非用数组包装起来。所以需要父元素或者Fragment包裹。
- 标签必须闭合
闭合标签分为自闭标签如,以及闭合标签,如
<li> <li/>。 - 使用驼峰式命名法给大部分属性命名。
JSX最终转化为JS,JSX属性变成JS对象中的键值对。JS对变量命名有限制,不能包含-符号或者class等等保留字。所以React中大部分HTML和SVG属性都用驼峰式命名法。对于class这样的保留字,要用className代替。
注意:对于aria-*和data-*的属性时用带-符号带HTML格式书写的。
4.使用引号传递字符串,{}动态指定src或alt的值,使用大括号{}编写JavaScript
引号传递字符串:
export default function Avatar() {
return (
<img
className="avatar"
src="https://i.imgur.com/7vQD0fPs.jpg"
alt="Gregorio Y. Zara"
/>
);
}
用作紧跟在 = 符号后的属性:
export default function Avatar() {
const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
const description = 'Gregorio Y. Zara';
return (
<img
className="avatar"
src={avatar}
alt={description}
/>
);
}
可以作为类似于模版字符串的功能:
export default function TodoList() {
const name = 'Gregorio Y. Zara';
return (
<h1>{name}'s To Do List</h1>
);
}
或者是函数调用:
const today = new Date();
function formatDate(date) {
return new Intl.DateTimeFormat(
'zh-CN',
{ weekday: 'long' }
).format(date);
}
export default function TodoList() {
return (
<h1>To Do List for {formatDate(today)}</h1>
);
}
- 使用双大括号:描述JSX中的CSS和对象
传递对象,需要用双大括号包裹对象,比如传递内联样式:双大括号知识包在JSX大括号内的JavaScript对象。
export default function TodoList() {
return (
<ul style={{
backgroundColor: 'black',
color: 'pink'
}}>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
);
}
注意:内联style属性需要用驼峰命名法编写。
<ul style="background-color: black"> 应该写成 <ul style={{ backgroundColor:'black'}}