当前位置:首页 > 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过渡或动画库增强用户体验:

react实现弹窗组件

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;
}

可复用高阶组件

创建高阶组件封装弹窗逻辑:

react实现弹窗组件

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>

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

相关文章

vue动态组件实现

vue动态组件实现

Vue 动态组件实现方法 使用 component 标签与 is 属性 通过 Vue 内置的 <component> 标签和 is 属性实现动态组件切换。is 的值可以是已注册的组件名或导…

vue实现水印组件

vue实现水印组件

Vue 水印组件实现 基础水印组件实现 创建一个基础水印组件,通过 props 接收文本、颜色、大小等参数: <template> <div class="watermark-…

vue组件传值实现分页

vue组件传值实现分页

Vue组件传值实现分页的方法 在Vue中实现分页功能,通常需要父子组件之间的数据传递。以下是几种常见的传值方式: 使用props传递数据 父组件通过props向子组件传递当前页码和总页数等分页信息:…

vue实现下拉刷新组件

vue实现下拉刷新组件

Vue 下拉刷新组件实现 核心思路 通过监听 touch 事件计算滑动距离,结合 CSS 过渡动画实现下拉效果,触发刷新回调。 基础实现步骤 监听 touch 事件 在组件 mounted 阶段绑定…

vue组件实现

vue组件实现

Vue 组件实现 Vue 组件是 Vue.js 的核心特性之一,允许开发者将 UI 拆分为独立、可复用的模块。以下是实现 Vue 组件的几种常见方式: 单文件组件(SFC) 单文件组件是 Vue…

react moment如何使用

react moment如何使用

安装 react-moment 通过 npm 或 yarn 安装 react-moment: npm install react-moment 或 yarn add react-moment…