当前位置:首页 > 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)实现动画:

// 配合 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 属性和键盘事件处理:

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 实现dialog组件

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

相关文章

vue实现下拉刷新组件

vue实现下拉刷新组件

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

vue实现下拉框组件

vue实现下拉框组件

Vue 下拉框组件实现 基础实现 创建基础下拉框组件,使用v-model实现双向数据绑定: <template> <div class="dropdown">…

电脑如何安装react

电脑如何安装react

安装 Node.js 和 npm React 依赖于 Node.js 和 npm(Node Package Manager)。从 Node.js 官网下载并安装最新稳定版本,安装完成后会自动包含 np…

如何react页面

如何react页面

创建 React 页面 使用 create-react-app 快速初始化项目: npx create-react-app my-app cd my-app npm start 基础页面结构 在…

react性能如何

react性能如何

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

如何选购react

如何选购react

选购 React 相关产品或服务的建议 React 是一个用于构建用户界面的 JavaScript 库,广泛应用于前端开发。以下是选购 React 相关产品(如课程、书籍、工具、组件库等)的参考方法:…