Table of Contents

1、概述

前面一章,我们学习了如何利用函数创建一个 React 组件。但是由于没有学习如何传入参数,所以灵活性比较差。

我们接下来要思考的一个问题,如果,我们想要往函数组件中,传入一些参数应该怎么办呢?

code.ts
1
function Profile(props) {
2
return (
3
<div>
4
<h1>{props.name}</h1>
5
</div>
6
)
7
}

Props

在 React 中,我们通常将参数称为 Props。他通过在元素标签中,添加属性的方式向组件内容传入参数。例如,我们封装了一个 Profile 组件,但是,这个组件需要展示不同用户的信息,因此,我们把用户的信息作为参数传入到组件中。

那么,在使用 Profile 组件时,就会有如下的写法,此时,我们将 avatarnamedescription 作为参数传入到组件中。

code.ts
1
<Profile
2
avatar="https://i.imgur.com/1bX5QH6.jpg"
3
name="Lin Lanying"
4
description="Lin Lanying (1918-2003), a native of Putian, Fujian, was a Chinese physicist and academician of the Chinese Academy of Sciences..."
5
/>

所有的参数,都会聚合到一个 props 对象中,因此在组件内部,我们可以通过 props 来获取到传入的参数。例如,我们可以在组件中,通过 props.avatar 来获取到 avatar 参数,通过 props.name 来获取到 name 参数。并且,我们也可以通过 props.description 来获取到 description 参数。

预览
index.tsx
app.tsx
1
export default function Profile(props) {
2
const avatar = props.avatar
3
const name = props.name
4
const description = props.description
5
6
return (
7
<div className='flex items-center gap-4'>
8
<img
9
className='w-40 rounded-xl'
10
src={avatar}
11
alt={name}
12
/>
13
<div>
14
<p className='!mt-0'>
15
<strong>name:</strong> {name}
16
</p>
17
<p className='!mb-0'>
18
{description}
19
</p>
20
</div>
21
</div>
22
)
23
}

2、Props 的类型

如果要结合 TypeScript 来使用,我们通常需要为 props 添加类型声明。例如,在上一个组件中,我们需要为 Profile 组件添加如下类型声明

预览
index.tsx
app.tsx
1
interface ProfileProps {
2
avatar: string,
3
name: string,
4
description: string,
5
}
6
7
export default function Profile(props: ProfileProps) {
8
const avatar = props.avatar
9
const name = props.name
10
const description = props.description
11
12
return (
13
<div className='flex items-center gap-4'>
14
<img
15
className='w-40 rounded-xl'
16
src={avatar}
17
alt={name}
18
/>
19
<div>
20
<p className='!mt-0'>
21
<strong>name:</strong> {name}
22
</p>
23
<p className='!mb-0'>
24
{description}
25
</p>
26
</div>
27
</div>
28
)
29
}

Props 的类型声明,严格符合基础的 TypeScript 语法。如果有的参数不是必传的,我们可以在类型声明中,添加 ? 符号来表示这个参数是可选的。

code.ts
1
interface ProfileProps {
2
avatar: string,
3
name: string,
4
description?: string,
5
}

3、Props 解构获取

由于 Props 是一个正常的 JavaScript 对象,因此,我们也可以通过解构的方式,来获取到 Props 中的参数。例如,我们可以在组件中,通过 ES6 的解构语法来获取到 avatarnamedescription 参数。

如下所示

profile.tsx
1
function Profile(props: ProfileProps) {
2
const { avatar, name, description } = props
3
4
return (
5
...
6
)
7
}

当然,更激进一点的做法是在函数参数中,直接解构获取。不过这样写有可能会降低代码的可读性,大家在使用时应该谨慎选择。

profile.tsx
1
function Profile({ avatar, name, description }: ProfileProps) {
2
return (
3
...
4
)
5
}

4、Props 展开运算符

如果我们有一个字面量对象,此时,对象属性的 key 值与 props 对象的 key 值相同,那么,我们也可以通过展开运算符的方式,将对象的属性展开到 props 对象中。

app.tsx
1
function App() {
2
const userinfo = {
3
avatar: 'https://i.imgur.com/szV5sdG.jpg',
4
name: 'Maria Skłodowska-Curie',
5
description: 'Maria Salomea Skłodowska-Curie[a] (ur. 7 listopada 1867 w Warszawie, zm. 4 lipca 1934 w Passy) – polsko-francuska uczona w dziedzinach fizyki doświadczalnej i chemii fizycznej...',
6
}
7
8
return (
9
<Profile {...userinfo} />
10
)
11
}

这等价于

code.ts
1
<Profile
2
avatar="https://i.imgur.com/szV5sdG.jpg"
3
name="Maria Skłodowska-Curie"
4
description="Maria Salomea Skłodowska-Curie[a] (ur. 7 listopada 1867 w Warszawie, zm. 4 lipca 1934 w Passy) – polsko-francuska uczona w dziedzinach fizyki doświadczalnej i chemii fizycznej..."
5
/>
预览
index.tsx
app.tsx
1
interface ProfileProps {
2
avatar: string,
3
name: string,
4
description: string,
5
}
6
7
export default function Profile(props: ProfileProps) {
8
const { avatar, name, description } = props
9
10
return (
11
<div className='flex items-center gap-4'>
12
<img
13
className='w-40 rounded-xl'
14
src={avatar}
15
alt={name}
16
/>
17
<div>
18
<p className='!mt-0'>
19
<strong>name:</strong> {name}
20
</p>
21
<p className='!mb-0'>
22
{description}
23
</p>
24
</div>
25
</div>
26
)
27
}

有的时候,一个对象字段特别多,但是其中大部分字段都是与 props 对象的 key 相同,但是其中有个别字段是与 props 对象的 key 不同,那么,我们可以通过如下的方式来进行处理

app.tsx
1
function App() {
2
const userinfo = {
3
avatar: 'https://i.imgur.com/szV5sdG.jpg',
4
name: 'Maria Skłodowska-Curie',
5
desc: 'Maria Salomea Skłodowska-Curie[a] (ur. 7 listopada 1867 w Warszawie, zm. 4 lipca 1934 w Passy) – polsko-francuska uczona w dziedzinach fizyki doświadczalnej i chemii fizycznej...',
6
}
7
8
// 单独将不同的字段提取出来
9
const { desc, ...other } = userinfo
10
11
return (
12
<Profile {...other} description={desc} />
13
)
14
}

如果在项目开发中,我们希望有一个组件可以方便的帮助我们定向到另外一个页面,例如我们从这个课程,跳转到另外一个课程中,那么,我们就可以借助上面所学到的知识,来自定义一个 Link 组件。

完整的代码和演示如下所示

预览
app.tsx
link.tsx
1
import Link from './link'
2
3
export default function App() {
4
const links = {
5
href: '/r19plus',
6
title: 'React 19 . 架构尊享版',
7
desc: '加油学习,我在 React 19 的架构尊享版中等你哦 (ง•_•)ง',
8
}
9
10
return (
11
<Link {...links} />
12
)
13
}
14

ok,学习了这些基础知识之后,我们接下来,再来基于 img 标签封装一个头像组件,来巩固一下学习。

专栏首页
到顶
专栏目录