示例代码:
import { useClassName } from '@/hook/useClassName';
import { Modal } from 'antd';
import React, { ForwardedRef, forwardRef, useImperativeHandle, useState } from 'react';
import styled from '@emotion/styled';
import MyForm from '@/components/combinedComponents/MyForm/MyForm';
/** 暴露出的ref */
type DialogRef = {
openDialog: () => void;
};
export interface IProps extends ICompProps {
/** 指定Ref获取的节点信息 */
ref?: ForwardedRef<DialogRef>;
}
const DialogAddOrEdit = forwardRef(function (props: IProps, ref: ForwardedRef<DialogRef>) {
const { className, style } = props;
const localClassName = useClassName('DialogAddOrEdit', className);
const [isModalOpen, setIsModalOpen] = useState(false);
const showModal = () => {
setIsModalOpen(true);
};
const handleOk = () => {
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
/** 打开会话框 */
const openDialog = () => {
setIsModalOpen(true);
};
/** 暴露出函数给父组件使用 */
useImperativeHandle<DialogRef, DialogRef>(ref, () => ({ openDialog }));
return (
<RootModal
className={localClassName}
style={style}
title="新增/修改资源"
open={isModalOpen}
onOk={handleOk}
onCancel={handleCancel}>
<MyForm>我的表单</MyForm>
</RootModal>
);
});
DialogAddOrEdit.defaultProps = {} as Partial<IProps>;
export default DialogAddOrEdit; //as React.FC<IProps>
const RootModal = styled(Modal)`
&.DialogAddOrEdit {
}
`;
关键点:
内置函数【forwardRef】【useImperativeHandle】打包使用.
forwardRef(function (props: IProps, ref: ForwardedRef<any>) {})
forwardRef用来包裹函数组件,为函数组件扩展第二个参数ref: ForwardedRef<any>;
useImperativeHandle<DialogRef, DialogRef>(ref, () => ({ openDialog }));
useImperativeHandle用来暴露出具体的内容.
泛型1:要暴露的实体对象格式,如 {a:string,b:string};
泛型2:从泛型1中限制出具体的子集进行暴露, 如{b:string};(最终将以b的值为准进行代码提示)
简单来说,多数时候,两者都是一样的就行.
参数1:函数组件传递过来的参数,直接透传就行.
参数2:用函数返回需要暴露的对象.
参数3:依赖,大多数时候不需要填.
- 完 -