This project demonstrates how to use React Portals together with styled-components to create a modal dialog that renders outside the main React app hierarchy.
This project was bootstrapped with Create React App.
- Node.js (v14 or higher recommended)
- npm
npm installnpm startOpen http://localhost:3000 to view it in your browser.
This project uses styled-components for styling React components.
To add styled-components to your project, run:
npm install styled-componentsYou can then import and use it in your components:
import styled from 'styled-components';
const Button = styled.button`
background: #007bff;
color: white;
padding: 8px 16px;
border: none;
border-radius: 4px;
`;The modal is rendered using React Portals. Make sure your public/index.html contains:
<div id="root"></div>
<div id="modal-root"></div>The Modal component is located in src/components/Modal.js:
import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';
const ModalWrapper = styled.div`
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
`;
const Modal = ({ children, onClose }) => {
const el = document.createElement('div');
useEffect(() => {
const modalRoot = document.getElementById('modal-root');
if (!modalRoot) return;
modalRoot.appendChild(el);
return () => {
modalRoot.removeChild(el);
};
}, [el]);
return ReactDOM.createPortal(
<ModalWrapper>
{children}
<button onClick={onClose}>Close Modal</button>
</ModalWrapper>,
el
);
};
export default Modal;Note:
The modalRoot lookup is now inside the useEffect hook to ensure it works correctly in both browser and test environments.
The App component demonstrates how to use the modal:
import React, { useState } from 'react';
import Modal from './components/Modal';
const App = () => {
const [showModal, setShowModal] = useState(false);
const toggleModal = () => {
setShowModal(!showModal);
};
return (
<div>
<h1>Styled Modal with React Portals</h1>
<button onClick={toggleModal}>Toggle Modal</button>
{showModal && (
<Modal onClose={toggleModal}>
<h2>Modal Title</h2>
<p>This is the modal content.</p>
</Modal>
)}
</div>
);
};
export default App;This project uses React Testing Library and Jest for unit testing.
The Modal and App tests ensure correct portal rendering and modal behavior.
To run tests:
npm testThis project is licensed under the MIT License.
