# React技巧之将对象作为props传递给组件
原文链接:https://bobbyhadz.com/blog/react-typescript-pass-object-as-props (opens new window)
作者:Borislav Hadzhiev (opens new window)
正文从这开始~
# 总览
在React TypeScript中将对象作为props
传递给组件:
- 为对象的类型定义一个接口。
- 将一个指定类型的对象传递给子组件,例如:
<Employee {...obj} />
。
// App.tsx
interface EmployeeProps {
name: string;
age: number;
country: string;
}
function Employee({name, age, country}: EmployeeProps) {
return (
<div>
<h2>{name}</h2>
<h2>{age}</h2>
<h2>{country}</h2>
</div>
);
}
export default function App() {
const obj = {name: 'Alice', age: 29, country: 'Austria'};
return (
<div>
<Employee {...obj} />
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 详情
我们使用扩展运算符语法(...
)将一个对象的属性作为props
传递给一个组件。
EmployeeProps
接口表示一个具有3个属性的对象。
思考这个语法的一个简单方法是,我们在预期有0个或更多键值对的地方取出对象的属性。
// App.js
const obj2 = {...{a: 1, b: 2}};
console.log(obj2); // 👉️ {a: 1, b: 2}
1
2
3
4
5
2
3
4
5
现在Employee
组件可以解构并使用所有已传递的props
。
有时你可能不会事先知道所有对象属性的名称和类型。
// App.tsx
interface EmployeeProps {
[key: string]: any; // 👈️ allows dynamic keys and values
name: string;
age: number;
country: string;
}
function Employee({name, age, country, tasks, salary}: EmployeeProps) {
return (
<div>
<h2>{name}</h2>
<h2>{age}</h2>
<h2>{country}</h2>
<h2>{salary}</h2>
<h2>{JSON.stringify(tasks)}</h2>
</div>
);
}
export default function App() {
const obj = {name: 'Alice', age: 29, country: 'Austria'};
// 👇️ can pass properties we haven't specified in advance
const obj2 = {tasks: ['dev', 'test'], salary: 100};
return (
<div>
<Employee {...obj} {...obj2} />
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{[key: string]: any}
语法是TypeScript
中的索引签名,当我们无法提前得知一个类型所有的属性和值的类型时,就可以使用该语法。
示例中的索引签名意味着,当对象被索引为
string
时,将会返回any
类型的值。
示例中的EmployeeProps
意味着,可以向组件传递name
、age
和country
指定属性,也可以向组件传递其他指向任何类型值的动态键。
如果你想要一个具有动态键和值的对象,而不要必需属性,那么就移除name
、age
和country
属性,只保留索引签名。
如果你把整个对象作为prop
传递,你将不得不在子组件中访问该对象的属性。
// App.tsx
interface EmployeeProps {
data: { // 👈️ have to nest properties
name: string;
age: number;
country: string;
};
}
function Employee({data}: EmployeeProps) {
return (
<div>
<h2>{data.name}</h2>
<h2>{data.age}</h2>
<h2>{data.country}</h2>
</div>
);
}
export default function App() {
const obj = {name: 'Alice', age: 29, country: 'Austria'};
// 👇️ passing data prop that is an object
return (
<div>
<Employee data={obj} />
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
需要注意的是,我们必须在接口中指定data
属性。
你可以通过更深一层的解构来避免访问data
对象上的每个属性。
// App.tsx
interface EmployeeProps {
data: {
name: string;
age: number;
country: string;
};
}
// 👇️ destructure one level deeper
function Employee({data: {name, age, country}}: EmployeeProps) {
return (
<div>
<h2>{name}</h2>
<h2>{age}</h2>
<h2>{country}</h2>
</div>
);
}
export default function App() {
const obj = {name: 'Alice', age: 29, country: 'Austria'};
return (
<div>
<Employee data={obj} />
</div>
);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
然而,使用扩展运算符语法(...
)来将对象的键值对拆包为props
时,语法就干净多了。