当前位置:首页 > React

react 实现dialog组件

2026-01-26 17:31:26React

实现 React Dialog 组件的方法

使用 React 内置 API 创建基础 Dialog

通过 ReactDOM.createPortal 将 Dialog 渲染到 body 元素下,避免层级问题:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

const Dialog = ({ isOpen, onClose, children }) => {
  if (!isOpen) return null;

  return ReactDOM.createPortal(
    <div className="dialog-overlay">
      <div className="dialog-content">
        {children}
        <button onClick={onClose}>Close</button>
      </div>
    </div>,
    document.body
  );
};

// 使用示例
function App() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div>
      <button onClick={() => setIsOpen(true)}>Open Dialog</button>
      <Dialog isOpen={isOpen} onClose={() => setIsOpen(false)}>
        <h2>Dialog Title</h2>
        <p>This is dialog content</p>
      </Dialog>
    </div>
  );
}

添加动画效果

使用 CSS transition 或第三方库(如 framer-motion)实现动画:

react 实现dialog组件

// 配合 CSS
.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.dialog-overlay[data-state='open'] {
  opacity: 1;
}

.dialog-content {
  background: white;
  padding: 20px;
  border-radius: 4px;
  transform: translateY(20px);
  transition: transform 0.3s ease;
}

.dialog-overlay[data-state='open'] .dialog-content {
  transform: translateY(0);
}

支持无障碍访问

添加 ARIA 属性和键盘事件处理:

react 实现dialog组件

const Dialog = ({ isOpen, onClose, children }) => {
  useEffect(() => {
    const handleKeyDown = (e) => {
      if (e.key === 'Escape') onClose();
    };

    if (isOpen) {
      document.addEventListener('keydown', handleKeyDown);
      document.body.style.overflow = 'hidden';
    }

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
      document.body.style.overflow = '';
    };
  }, [isOpen, onClose]);

  if (!isOpen) return null;

  return ReactDOM.createPortal(
    <div 
      className="dialog-overlay"
      onClick={onClose}
      role="dialog"
      aria-modal="true"
    >
      <div 
        className="dialog-content" 
        onClick={e => e.stopPropagation()}
      >
        {children}
        <button onClick={onClose}>Close</button>
      </div>
    </div>,
    document.body
  );
};

使用第三方库快速实现

对于更复杂的需求,可以考虑使用现成的 Dialog 组件库:

// 使用 @radix-ui/react-dialog
import * as Dialog from '@radix-ui/react-dialog';

function RadixDialog() {
  return (
    <Dialog.Root>
      <Dialog.Trigger>Open</Dialog.Trigger>
      <Dialog.Portal>
        <Dialog.Overlay className="dialog-overlay" />
        <Dialog.Content className="dialog-content">
          <Dialog.Title>Title</Dialog.Title>
          <Dialog.Description>Description</Dialog.Description>
          <Dialog.Close>Close</Dialog.Close>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}

样式定制化建议

通过 CSS 变量或 props 实现主题定制:

// 通过 props 控制样式
<Dialog 
  size="large" 
  theme="dark"
  position="center"
/>

// 对应样式处理
.dialog-content[data-size='large'] {
  width: 800px;
}

.dialog-content[data-theme='dark'] {
  background: #333;
  color: white;
}

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

相关文章

vue实现倒计时组件

vue实现倒计时组件

实现基础倒计时功能 使用 Vue 的 data 和 methods 定义倒计时逻辑,通过 setInterval 更新剩余时间。 <template> <div>{{…

如何删除react

如何删除react

卸载 React 项目依赖 打开项目根目录下的 package.json 文件,删除所有包含 react、react-dom 或其他 React 相关库的依赖项。保存文件后运行以下命令: npm u…

react性能如何

react性能如何

React 性能特点 React 通过虚拟 DOM(Virtual DOM)和高效的 diff 算法优化性能。虚拟 DOM 减少了直接操作真实 DOM 的开销,仅在必要时更新变化的部分。React 的…

react如何收录

react如何收录

React 收录方法 React 的收录主要涉及搜索引擎优化(SEO)和预渲染技术。由于 React 是单页应用(SPA),默认情况下内容由 JavaScript 动态生成,可能导致搜索引擎爬虫难以收…

如何用react

如何用react

使用React的基本步骤 安装Node.js和npm 确保系统已安装Node.js和npm。Node.js自带npm,可从官网下载安装包。安装完成后,通过命令行验证版本: node -v npm -…

如何构建react

如何构建react

构建 React 项目的步骤 安装 Node.js 和 npm 确保系统已安装 Node.js(包含 npm)。可通过命令行验证: node -v npm -v 使用 Create React Ap…