actually i’m working on a custom uikit library for React, and i wrote a lot of reusable component.
Now i want to create a good reusable Modal component, that must be rendered always on top of all elements, so i decided to use createPortal(). but now i have a few questions…
1: how can i create the div for portal (that should be inside index.html on a react app)?
2: can i do this in my library or must be manually created by the app owner?
Actually my (UNCOMPLETED) component looks like:
import React, {
FC,
MutableRefObject,
useEffect,
useRef,
} from 'react';
import {
RVModalContainer,
RVModalOverlay,
} from './styled';
import { RVModalProps } from './types';
import { createPortal } from 'react-dom';
const modalRoot = document.getElementById('modal-root');
const Modal: FC<RVModalProps> = ({ show, close }) => {
const contentRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
if (!show) {
return null;
}
return (
<>
{createPortal(
<RVModalOverlay>
<RVModalContainer
ref={contentRef}
>
example uncompleted text
</RVModalContainer>
</RVModalOverlay>,
modalRoot,
)}
</>
);
};
export default Modal;
It’ll be good if someone can explein me what is the best way to achieve the best re-usable result.
P.s. my library is made with storybook, rollupjs, typescript and styled components.
I’ve tried to create the modal-root div inside the component, but actually doesn’t work and i can’t see the result in storybook (the modal not appear and the modal-root div is not appended into the body.
what i’ve tried
const Modal: FC<RVModalProps> = ({ show, children }) => {
const modalRoot = document.createElement('div');
useEffect(() => {
modalRoot.id = 'modal-root';
document.body.appendChild(modalRoot);
return () => {
document.body.removeChild(modalRoot);
};
}, [modalRoot]);
if (!show) return null;
return createPortal(
<RVModalOverlay>
{children}
</RVModalOverlay>,
modalRoot
);
};
export default Modal;