当前位置:首页 > React

react实现弹窗组件

2026-01-26 20:57:28React

实现基础弹窗组件

创建一个基础的弹窗组件需要管理组件的显示状态和内容渲染。以下是一个简单实现:

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>

支持多种弹窗类型

扩展组件支持警告、确认等不同类型:

react实现弹窗组件

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>

标签: 组件react
分享给朋友:

相关文章

如何降低react版本

如何降低react版本

降低 React 项目版本的步骤 检查当前 React 版本 在项目根目录的 package.json 文件中查看 dependencies 或 devDependencies 下的 react 和…

vue radio组件实现

vue radio组件实现

Vue Radio 组件实现 在 Vue 中实现 Radio 组件可以通过原生 HTML 的 <input type="radio"> 结合 Vue 的响应式特性,或者使用第三方 UI 库…

vue实现穿梭框树组件

vue实现穿梭框树组件

Vue 穿梭框树组件实现 穿梭框树组件通常结合了树形结构和穿梭框功能,允许用户在左右两栏之间移动树节点数据。以下是基于 Vue 的实现方案: 核心功能设计 数据结构 树形数据通常采用嵌套结构,例如:…

uniapp倒计时组件

uniapp倒计时组件

uniapp倒计时组件实现方法 使用内置组件实现 uniapp提供了<countdown>组件用于倒计时功能,支持自定义格式和样式。示例代码如下: <countdown…

react如何引入

react如何引入

引入React的方法 React可以通过多种方式引入项目,具体取决于项目需求和开发环境。以下是常见的几种方法: 通过CDN引入 在HTML文件中直接通过CDN链接引入React和ReactDOM:…

react如何减少伤病

react如何减少伤病

减少React应用中的性能问题(避免"伤病") 优化React应用性能需要从组件渲染、状态管理和外部依赖等多方面入手。以下是关键优化策略: 使用React.memo进行组件记忆 对函数组件使用Rea…