封装一个模态框组件
createPortal
的 API 语法如下ReactDOM.createPortal(child, container)
// 模态框组件
const Modal = ({ onClose }) => {
return ReactDOM.createPortal(
<div style={styles.overlay} onClick={onClose}>
<div style={styles.modal} onClick={(e) => e.stopPropagation()}>
<h2>我是一个模态框</h2>
<button onClick={onClose}>关闭</button>
</div>
</div>,
document.body // 将 Modal 渲染到 body 上
);
};
// 样式
const styles = {
overlay: {
position: 'fixed',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: 1000,
},
modal: {
background: 'white',
padding: '20px',
borderRadius: '5px',
},
};
封装一个操作模态框的组件
const SetModel = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);
return (
<div>
<h1>React createPortal 示例</h1>
<button onClick={openModal}>打开模态框</button>
{isModalOpen && <Modal onClose={closeModal} />}
</div>
);
};
操作按钮在dom里
const Button = ({ onClose, container }) => {
return ReactDOM.createPortal(
<button onClick={onClose} className='bg-white'>111</button>,
container // 将 Modal 渲染到指定容器
);
};
const SetModel = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const expel = useRef(null); // 创建一个 ref 用于目标容器
const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);
useEffect(() => {
if (expel.current) {
console.log('expel current:', expel.current);
}
}, [expel.current]);
return (
<div >
<h1 className='bg-black' style={{ width: '200px', height: '200px' }} ref={expel}>React createPortal 示例</h1>
<button onClick={openModal}>打开模态框</button>
{/* 传递 ref 指向目标容器 */}
{isModalOpen && <Button onClose={closeModal} container={expel.current} />}
{/* {isModalOpen && <Modal onClose={closeModal} container={expel.current} />} */}
</div>
);
};