说明
通常情况下,React 子组件使用父组件的方法或值通过props传递,反过来,父组件如果需要子组件的方法就需要子组件将自己的方法暴露出去。以下是一个实例:
User.tsx
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 (<EditFilledonClick={(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><ButtononClick={() => {userEditRef.current.open();}}>新建</Button><Table columns={columns} dataSource={datasource} /><UserEdit ref={userEditRef} onSave={updateData} /></div>);
};export default User;
UserEdit.tsx
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) => {//propsconst { onSave } = props;// stateconst [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 (<Drawertitle={currentFormData ? '用户 | ' + currentFormData?.name : '用户 | 新建'}width="auto"open={userEditOpen}footer={null}onClose={onCancel}destroyOnClose><Form initialValues={currentFormData} onFinish={onFinish}><Form.Itemlabel="组名"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><ButtonhtmlType="button"onClick={onCancel}style={{ marginLeft: 8 }}>取消</Button></Form.Item></Form></Drawer>);
});export default UserEdit;
效果预览
1、stackblitz预览
2、InsCode预览