You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用React实现带淡入淡出效果的小型可复用弹窗

React小型可复用淡入淡出弹窗实现

直接封装无额外依赖的通用弹窗组件即可,完全可控尺寸、动画效果,一次封装全局可复用,不需要引入第三方UI库。

核心特性

  • 默认小尺寸自适应内容,不会出现占满全屏的问题
  • 自带淡入淡出过渡效果,动画时长可自定义
  • 支持全局调用,不需要每个页面重复写弹窗结构
  • 支持自定义位置、显示时长、内容样式

代码实现

首先新建弹窗组件文件:

1. 组件逻辑 Popup.jsx

import { useState, useEffect, useCallback } from 'react';
import './Popup.css';

// 全局调用方法句柄
let openPopup = null;

/**
 * 全局调用弹窗方法
 * @param {string|React.ReactNode} content 弹窗显示内容
 * @param {object} options 配置项
 * @param {number} options.duration 自动关闭时长,传0则不自动关闭
 * @param {string} options.position 弹窗位置:center/top/bottom
 */
export const showPopup = (content, options = {}) => {
  openPopup?.(content, options);
};

const Popup = () => {
  const [visible, setVisible] = useState(false);
  const [content, setContent] = useState('');
  const [config, setConfig] = useState({
    duration: 2000,
    position: 'center'
  });

  const handleClose = useCallback(() => {
    setVisible(false);
  }, []);

  useEffect(() => {
    openPopup = (content, options) => {
      setContent(content);
      setConfig(prev => ({ ...prev, ...options }));
      setVisible(true);
      if (options.duration !== 0) {
        setTimeout(handleClose, options.duration || 2000);
      }
    };
    return () => {
      openPopup = null;
    };
  }, [handleClose]);

  return (
    <>
      {/* 半透明遮罩,不需要可删除 */}
      {visible && <div className="popup-mask" onClick={handleClose} />}
      <div
        className={`popup-box popup-${config.position} ${visible ? 'fade-in' : 'fade-out'}`}
      >
        {content}
      </div>
    </>
  );
};

export default Popup;

2. 样式文件 Popup.css

/* 遮罩层 */
.popup-mask {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.1);
  z-index: 999;
}

/* 弹窗基础样式 小尺寸默认配置 */
.popup-box {
  position: fixed;
  z-index: 1000;
  min-width: 120px;
  max-width: 280px;
  padding: 12px 20px;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  font-size: 14px;
  line-height: 1.5;
  text-align: center;
  /* 淡入淡出动画配置 */
  transition: opacity 0.2s ease, transform 0.2s ease;
  opacity: 0;
  pointer-events: none;
}

/* 位置配置 */
.popup-center {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -48%);
}
.popup-top {
  top: 20%;
  left: 50%;
  transform: translate(-50%, -48%);
}
.popup-bottom {
  bottom: 20%;
  left: 50%;
  transform: translate(-50%, 52%);
}

/* 动画状态 */
.fade-in {
  opacity: 1;
  transform: translate(-50%, -50%);
  pointer-events: auto;
}
.fade-out {
  opacity: 0;
  pointer-events: none;
}

使用方法

  1. 先在项目根组件(如App.jsx)挂载一次弹窗,全项目共用:
import Popup from './Popup';

function App() {
  return (
    <div className="app-container">
      {/* 原有业务路由、组件 */}
      <Popup />
    </div>
  );
}
  1. 任意业务页面需要触发弹窗时,直接引入调用方法即可,不需要重复挂载组件:
import { showPopup } from './Popup';

// 业务逻辑中直接调用
const handleAction = () => {
  // 基础调用
  showPopup('操作已提交');
  // 自定义配置调用
  showPopup('内容已删除', {
    duration: 1500,
    position: 'top'
  });
};

自定义调整说明

  • 调整弹窗尺寸:直接修改.popup-box的min-width/max-width/padding属性即可
  • 调整淡入淡出速度:修改transition属性的时长数值
  • 支持复杂内容:showPopup方法的content参数支持传入React节点,可以放按钮、图片、表单等任意自定义内容
  • 不需要遮罩层直接删除对应JSX和样式代码即可

内容的提问来源于stack exchange,提问作者Sexy Guy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 07:34:23