useImperativeHandle 与 ref
2020-08-20 本文已影响0人
小遁哥
最近在用umi3.0 + antd4.0 重构以前用vue2.5写的项目。
想要的结果
const editModalRef = useRef<IEditModalRef>();
<EditModal ref={editModalRef}></EditModal>
可以通过editModalRef.current.showModal(true);
显示模态框,
EditModal
代码如下
import TNotes from '../../TNotes';
import {
useState,
useImperativeHandle,
forwardRef,
ForwardRefRenderFunction,
} from 'react';
import { Modal } from 'antd';
import React from 'react';
export interface IEditModalProps {}
export interface IEditModalState {
visible: boolean;
data: TNotes;
added: boolean;
}
export interface IEditModalRef {
showModal: (visible: boolean, data?: TNotes) => void;
}
const defaultState: IEditModalState = {
added: false,
visible: false,
data: {
content: '',
loadCount: 0,
base64: {},
createTime: null,
updateTime: null,
title: '',
},
};
export const EditModal: ForwardRefRenderFunction<
IEditModalRef,
IEditModalProps
> = (props, ref) => {
const [state, setState] = useState(defaultState);
useImperativeHandle(ref, () => ({
showModal: (visible, data) => {
setState((preState) => ({
...preState,
visible,
...(data ? { data } : { added: true }),
}));
},
}));
function onCancel() {
setState(defaultState);
}
const title = state.added ? '添加记事' : '编辑记事';
return (
<Modal
visible={state.visible}
title={title}
onCancel={onCancel}
></Modal>
);
};
export default forwardRef(EditModal);
还是复杂在类型声明上,其实forwardRef
点进去后
function forwardRef<T, P = {}>
(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;
render: ForwardRefRenderFunction<T, P>
就明确的说明了类型,只是我没反应过来只要加上这个声明就可以了...
另外泛型T
代表ref
的类型,P
代表props
的类型也秀到了我...
ForwardRefRenderFunction
是这样的
interface ForwardRefRenderFunction<T, P = {}> {
(props: PropsWithChildren<P>, ref: ((instance: T | null) => void) | MutableRefObject<T | null> | null): ReactElement | null;
PropsWithChildren
是这样的
type PropsWithChildren<P> = P & { children?: ReactNode };