I created a modal component that utilizes React’s context, and hooks for easy usage. But for some reason, the element that I want to render in the modal doesn’t appear.
Here’s my code for the ModalContainer which contains the provider and the modal
ModalContainer.tsx
export type ModalElement =
| React.ComponentClass<any, any>
| React.FC<any>
| JSX.Element;
const ModalContainer: React.FC = ({ children }) => {
const [visible, setVisible] = useState(false);
const modal = useRef<HTMLDivElement>(null);
const showModal = (element: ModalElement) => {
if (element && modal.current) {
if (React.isValidElement(element)) {
ReactDOM.render(element, modal.current);
} else {
const el = React.createElement(
element as React.ComponentClass<any, any> | React.FC<any>,
{}
);
ReactDOM.render(el, modal.current);
}
setVisible(true);
}
};
const dismissModal = () => {
setVisible(false);
};
return (
<ModalContext.Provider value={{ showModal, dismissModal }}>
{children}
<Modal visible={visible} onClose={dismissModal} ref={modal} />
</ModalContext.Provider>
);
};
export default ModalContainer;
useModal.ts
export const useModal = (element: ModalElement) => {
const context = useContext(ModalContext);
if (!context) {
Error(`Can't get modal context`);
}
const show = useCallback(() => {
context.showModal(element);
}, [context, element]);
const dismiss = useCallback(() => {
context.dismissModal();
}, [context]);
return [show, dismiss];
};
In a way that you’ll use it as such:
const DivModal: React.FC = () => {
return <div>Test</div>
}
const Component: React.FC = () => {
const [show, dismiss] = useModal(DivModal);
const onClick = () => {
show();
}
return <button onClick={onClick}/>
}
The problem seems to happen when I create an element using React.createElement
in the ModalContainer.tsx
found specifically in this line:
const el = React.createElement( element as React.ComponentClass<any, any> | React.FC<any>, {} ); ReactDOM.render(el, modal.current);
The modal renders properly if I replace el
in the render function with a test JSX such as <div>test</div>
. Can’t really figure out what’s wrong so I’ll post it here just in case anyone knows what the problem is. Thanks!