004-学习React-绘制项目界面
React学习系列 - 来源React英文文档
章节链接: https://beta.reactjs.org/learn/describing-the-ui
绘制项目界面
- React是一个绘制项目图形界面的JS库
- 思想是组件化,把一些小的单元像按钮、文本、图片做成可复用、可嵌套的组件
- 所有在屏幕上展示的内容都可以被拆分成组件
编写你的第一个React组件
- 个人介绍组件示例
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>
);
}
导入导出组件
- 你可以在一个文件编写声明多个组件
- 但随着文件内容增多,你想查找起来就越来越困难
- 所以好的办法是单独编写一个文件声明组件并导出,在需要它的地方导入
- 上面的Profile组件单独声明如下
export default function Profile() {
return (
<img
src="https://i.imgur.com/QIrZWGIs.jpg"
alt="Alan L. Hart"
/>
);
}
- 在需要的地方导入Profile组件
import Profile from './Profile.js';
export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
用JSX语法编写标签元素
-
每个React组件都是一个包含很多标签元素的函数
-
它会渲染到浏览器页面的
-
React组件使用JavaScript的扩展语法来编写页面的内容元素
-
JSX语法 JavaScript X= JavaScript Extension
-
它的语法比较严格,能够展示很多的动态信息
-
如果把HTML的内容直接复制粘贴到React组件里,有的语法不兼容
-
所以HTML的内容并不会总是生效
-
HTML内容的必须由一对闭合标签包裹
export default function TodoList() {
return (
<>
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve spectrum technology</li>
</ul>
</>
);
}
用JSX的括号语法编写JavaScript
- JSX语法可以在JavaScript文件中像HTML一样的标签
- 同时在里面包含着业务逻辑和页面内容
- 为了在JSX语法内容中添加一些逻辑或给属性赋动态变化的值
- 需要用到括号的语法来为编写JavaScript提供一些便利
const person = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
<img
className="avatar"
src="https://i.imgur.com/7vQD0fPs.jpg"
alt="Gregorio Y. Zara"
/>
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
向组件传递props
- React组件使用Props互相通信
- 每个父组件可以通过Props传递给子组件一些信息
- Props可能让你想起HTML属性
- 但你可以通过Props传参传递任何JavaScript值
- 包括对象、数组、函数、甚至JSX代码
- 一个综合示例
function getImageUrl(person, size = 's') {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
export default function Profile() {
return (
<Card>
<Avatar
size={100}
person={{
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>
</Card>
);
}
function Avatar({ person, size }) {
return (
<img
className="avatar"
src={getImageUrl(person)}
alt={person.name}
width={size}
height={size}
/>
);
}
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
条件渲染
- 你的组件通常需要根据不同的条件渲染不同的内容
- 可以使用if条件语句、&&运算符、expr ? x : y 三元条件表达式
function Item({ name, isPacked }) {
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
}
export default function PackingList() {
return (
<section>
<h1>Sally Ride's Packing List</h1>
<ul>
<Item
isPacked={true}
name="Space suit"
/>
<Item
isPacked={true}
name="Helmet with a golden leaf"
/>
<Item
isPacked={false}
name="Photo of Tam"
/>
</ul>
</section>
);
}
列表渲染
- 经常会遇到展示一些数据集合的情况
- 可以使用JavaScript的filter和map展示和处理数据
- 对于集合中的每一项,需要给它指定一个key
- 通常情况下,可以使用来自数据库的唯一id来标记它
- 这样React可以很方便地维护这些数据,即使这些列表发生变化的情况
export default function List() {
const listItems = people.map(person =>
<li key={person.id}>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}:</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
return (
<article>
<h1>Scientists</h1>
<ul>{listItems}</ul>
</article>
);
}
- 用到的数据和函数
export const people = [{
id: 0,
name: 'Creola Katherine Johnson',
profession: 'mathematician',
accomplishment: 'spaceflight calculations',
imageId: 'MK3eW3A'
}, {
id: 1,
name: 'Mario José Molina-Pasquel Henríquez',
profession: 'chemist',
accomplishment: 'discovery of Arctic ozone hole',
imageId: 'mynHUSa'
}, {
id: 2,
name: 'Mohammad Abdus Salam',
profession: 'physicist',
accomplishment: 'electromagnetism theory',
imageId: 'bE7W1ji'
}, {
id: 3,
name: 'Percy Lavon Julian',
profession: 'chemist',
accomplishment: 'pioneering cortisone drugs, steroids and birth control pills',
imageId: 'IOjWm71'
}, {
id: 4,
name: 'Subrahmanyan Chandrasekhar',
profession: 'astrophysicist',
accomplishment: 'white dwarf star mass calculations',
imageId: 'lrWQx8l'
}];
export function getImageUrl(person) {
return (
'https://i.imgur.com/' +
person.imageId +
's.jpg'
);
}