说明

通常情况下,React 子组件使用父组件的方法或值通过props传递,反过来,父组件如果需要子组件的方法就需要子组件将自己的方法暴露出去。以下是一个实例:

User.tsx

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import React, { FC, useEffect, useState, useRef } from 'react';
import { Button, Table } from 'antd';
import UserEdit, { UserEditRef } from './UserEdit';
import { EditFilled } from '@ant-design/icons';

interface User {
desc?: string;
name?: string;
}
const User: FC = () => {
const userEditRef = useRef<UserEditRef>(null);
const columns: any = [
{
title: '名称',
dataIndex: 'name',
key: 'name',
},
{
title: '描述',
dataIndex: 'desc',
key: 'desc',
},
{
title: '操作',
render: (_: string, record: User) => {
return (
<EditFilled
onClick={(e) => {
userEditRef.current?.open(record);
}}
/>
);
},
},
];
const [datasource, setDatasource] = useState<User[]>([
{
desc: 'I am Tom',
name: 'Tom',
},
{
desc: 'I am Marry',
name: 'Marry',
},
]);

const updateData = (data?: User) => {
const datas = [data, ...datasource];
setDatasource(datas);
};

return (
<div>
<Button
onClick={() => {
userEditRef.current.open();
}}
>
新建
</Button>
<Table columns={columns} dataSource={datasource} />
<UserEdit ref={userEditRef} onSave={updateData} />
</div>
);
};

export default User;

UserEdit.tsx

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { useState, useImperativeHandle, forwardRef } from 'react';
import { Form, Input, Drawer, Button } from 'antd';

interface User {
userId?: number;
desc?: string;
name?: string;
}

interface PropType {
onSave: Function;
}

export interface UserEditRef {
open: (currentUser?: User) => void;
}

const UserEdit = forwardRef<UserEditRef, PropType>((props, ref) => {
//props
const { onSave } = props;
// state
const [userEditOpen, setUserEditOpen] = useState(false);
const [currentFormData, setCurrentFormData] = useState<User>();

// 暴露给父组件的属性,open是打开抽屉的方法
useImperativeHandle(ref, () => ({
open: (currentUser?: User) => {
setUserEditOpen(true);
setCurrentFormData(currentUser);
},
}));

const onCancel = () => {
setUserEditOpen(false);
};

const onFinish = (values: any) => {
onSave(values);
setUserEditOpen(false);
};

return (
<Drawer
title={
currentFormData ? '用户 | ' + currentFormData?.name : '用户 | 新建'
}
width="auto"
open={userEditOpen}
footer={null}
onClose={onCancel}
destroyOnClose
>
<Form initialValues={currentFormData} onFinish={onFinish}>
<Form.Item
label="组名"
name="name"
rules={[{ required: true, message: '请输入用户名!' }]}
>
<Input />
</Form.Item>
<Form.Item label="描述" name="desc">
<Input.TextArea />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
提交
</Button>
<Button
htmlType="button"
onClick={onCancel}
style={{ marginLeft: 8 }}
>
取消
</Button>
</Form.Item>
</Form>
</Drawer>
);
});

export default UserEdit;

效果预览

React hooks子组件暴露方法示例