react实现弹窗组件
实现基础弹窗组件
创建一个基础的弹窗组件需要管理组件的显示状态和内容渲染。以下是一个简单实现:
import React, { useState } from 'react';
const Modal = ({ isOpen, onClose, children }) => {
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center">
<div className="bg-white p-6 rounded-lg shadow-lg">
{children}
<button
onClick={onClose}
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded"
>
关闭
</button>
</div>
</div>
);
};
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div>
<button onClick={() => setIsModalOpen(true)}>打开弹窗</button>
<Modal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
>
<h2>弹窗标题</h2>
<p>这里是弹窗内容...</p>
</Modal>
</div>
);
}
添加动画效果
使用CSS过渡或动画库增强用户体验:
import React, { useState } from 'react';
import { CSSTransition } from 'react-transition-group';
const Modal = ({ isOpen, onClose, children }) => {
return (
<CSSTransition
in={isOpen}
timeout={300}
classNames="modal"
unmountOnExit
>
<div className="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center">
<div className="bg-white p-6 rounded-lg shadow-lg">
{children}
<button onClick={onClose}>关闭</button>
</div>
</div>
</CSSTransition>
);
};
// CSS样式
.modal-enter {
opacity: 0;
}
.modal-enter-active {
opacity: 1;
transition: opacity 300ms;
}
.modal-exit {
opacity: 1;
}
.modal-exit-active {
opacity: 0;
transition: opacity 300ms;
}
可复用高阶组件
创建高阶组件封装弹窗逻辑:
import React, { useState } from 'react';
const withModal = (WrappedComponent) => {
return function WithModal(props) {
const [isOpen, setIsOpen] = useState(false);
const openModal = () => setIsOpen(true);
const closeModal = () => setIsOpen(false);
return (
<>
<WrappedComponent {...props} openModal={openModal} />
{isOpen && (
<div className="modal-overlay">
<div className="modal-content">
{props.children}
<button onClick={closeModal}>关闭</button>
</div>
</div>
)}
</>
);
};
};
// 使用示例
const ButtonWithModal = withModal(({ openModal }) => (
<button onClick={openModal}>打开弹窗</button>
));
使用Portal优化渲染
使用React Portal确保弹窗渲染在body根部:
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
const ModalPortal = ({ children }) => {
return ReactDOM.createPortal(
children,
document.getElementById('modal-root')
);
};
const Modal = ({ isOpen, onClose, children }) => {
if (!isOpen) return null;
return (
<ModalPortal>
<div className="modal-overlay">
<div className="modal-content">
{children}
<button onClick={onClose}>关闭</button>
</div>
</div>
</ModalPortal>
);
};
// 在public/index.html中添加<div id="modal-root"></div>
支持多种弹窗类型
扩展组件支持警告、确认等不同类型:
const Modal = ({ type, isOpen, onClose, onConfirm, children }) => {
if (!isOpen) return null;
return (
<div className="modal-overlay">
<div className={`modal-content ${type}`}>
{children}
<div className="modal-actions">
{type === 'confirm' && (
<button onClick={onClose}>取消</button>
)}
<button
onClick={type === 'confirm' ? onConfirm : onClose}
className={type === 'alert' ? 'primary' : ''}
>
{type === 'confirm' ? '确认' : '确定'}
</button>
</div>
</div>
</div>
);
};
// 使用示例
<Modal
type="confirm"
isOpen={isConfirmOpen}
onClose={() => setIsConfirmOpen(false)}
onConfirm={handleConfirm}
>
确定要执行此操作吗?
</Modal>






