「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」。
这是React清风拂面系列第三篇,上一篇请看这里
本篇文章,主要学习如何创建,自定义和有条件的展示React组件。
React 应用是有由一个个的“组件”构建。所谓组件其实就是一个可以写标记的函数。
组件可大可小,小的如一个按钮,大到整个应用。
下面就定义了2个组件
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>
);
}
引入和导出组件
可以用ES6的标准语法
import Profile from './Profile.js';
export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
JSX标记语言
从上面的例子看,React里面 return 语法叫做JSX,类似于HTML,但是有一些不同,你不能直接将HTML片段复制到 return 函数,可以通过htmltojsx来校验
JSX和花括号
花括号在JSX里面表示动态执行JS,因此你可以将一些变量用花括号包裹起来。
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>
);
}
组件通信
React里面通过 props 对象将父组件的值传给子组件
props的内容可以是对象,数组,函数甚至JSX
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
条件渲染
JSX支持原生JS语法,因此可以用 if,&&,?:等表达式。
function Item({ name, isPacked }) {
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
}
列表渲染
上面说过JSX支持原生JS写法,因此可以用ES6里面关于数组的一些操作比如map,filter 等。
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>
);
}
组件为纯函数
React组件是函数,在我们编写代码的时候,遵守React组件是纯函数的标准。
纯函数两大特点:
- 相同的入参,经过计算后一定会返回相同的结果。
- 在函数计算时,无副作用(IO、请求、修改外部变量、console.log)
let guest = 0;
function Cup() {
// 有副作用,修改了外部变量
guest = guest + 1;
return <h2>Tea cup for guest #{guest}</h2>;
}
应该改为
function Cup({ guest }) {
//参数由外部传入
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup guest={1} />
<Cup guest={2} />
<Cup guest={3} />
</>
);
}