当前位置:首页 > 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 组件传值实现分页 在Vue中实现分页功能,通常需要父子组件之间的数据传递。以下是几种常见的传值方法: 使用props和$emit 父组件通过props向子组件传递数据,子组件通过$emit…

react 如何执行

react 如何执行

安装 React 确保 Node.js 安装在本地环境中。通过以下命令创建新的 React 项目: npx create-react-app my-app 进入项目目录并启动开发服务器:…

react如何

react如何

React 基础概念 React 是一个用于构建用户界面的 JavaScript 库,专注于组件化开发。通过虚拟 DOM 和高效的渲染机制,React 能够实现高性能的 UI 更新。 安装 R…

react 如何继承

react 如何继承

在React中,组件继承并非推荐的设计模式(官方更推崇组合优于继承),但技术上仍可通过以下方式实现类似效果: 使用ES6类继承 通过extends关键字继承父组件类,子组件可访问父组件的生命…

vue动态组件实现

vue动态组件实现

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

vue实现水印组件

vue实现水印组件

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