nice-modal-react 使用文档

4 阅读4分钟

nice-modal-react 是一个轻量、灵活的 React 模态框(Modal)管理库,它通过 函数式调用 + Hook 管理状态 的方式,帮助开发者摆脱繁琐的状态控制(如 visible, onClose),实现更简洁、解耦的模态框开发体验。


📦 安装

npm install nice-modal-react

或使用 yarn:

yarn add nice-modal-react

🧩 基本结构:必须包裹 Provider

在应用根部使用 <NiceModalProvider> 包裹你的组件树。

// App.jsx
import React from 'react';
import { NiceModalProvider } from 'nice-modal-react';
import MainPage from './MainPage';

function App() {
  return (
    <NiceModalProvider>
      <div className="App">
        <MainPage />
      </div>
    </NiceModalProvider>
  );
}

export default App;

⚠️ 所有功能都依赖此 Provider,请确保已正确引入。


✅ 使用方式一:函数式调用(推荐)

最常用的模式,通过 show() 函数动态弹出模态框。

步骤 1:创建并包装 Modal 组件

// components/MyModal.jsx
import React from 'react';
import { useModal } from 'nice-modal-react';

const MyModal = ({ title = '提示', children }) => {
  const { visible, hide } = useModal();

  if (!visible) return null;

  return (
    <div className="modal-overlay">
      <div className="modal-content">
        <h3>{title}</h3>
        <p>{children}</p>
        <button onClick={hide}>关闭</button>
      </div>
    </div>
  );
};

// 使用 niceModal 包装组件(关键步骤)
export default niceModal(MyModal);

💡 注意:必须使用 niceModal() 高阶函数包装组件才能被识别。

步骤 2:函数式调用

import { show } from 'nice-modal-react';
import MyModal from './components/MyModal';

function App() {
  const openModal = () => {
    show(MyModal, {
      title: '欢迎',
      children: '这是一个简单的模态框',
    });
  };

  return <button onClick={openModal}>打开模态框</button>;
}

✅ 优点:

  • 无需维护 visible 状态
  • 支持传参
  • 调用简单清晰

✅ 使用方式二:使用 useModal 控制行为

在 Modal 内部使用 useModal() 获取控制能力。

可用属性与方法:

属性/方法类型说明
visibleboolean当前是否可见
hide()function隐藏当前 modal
remove()function销毁实例(从 DOM 移除)
resolve(value)function返回结果(用于异步等待)
reject(err)function抛出错误(配合 await 使用)

示例:带返回值的确认框

// components/ConfirmModal.jsx
import React from 'react';
import { useModal } from 'nice-modal-react';

const ConfirmModal = ({ message = '确认操作?' }) => {
  const { visible, resolve } = useModal();

  if (!visible) return null;

  return (
    <div className="modal-overlay">
      <div className="modal-content">
        <p>{message}</p>
        <button onClick={() => resolve(true)}>确定</button>
        <button onClick={() => resolve(false)}>取消</button>
      </div>
    </div>
  );
};

export default niceModal(ConfirmModal);

异步调用并获取结果:

import { show } from 'nice-modal-react';
import ConfirmModal from './components/ConfirmModal';

const handleDelete = async () => {
  const confirmed = await show(ConfirmModal, {
    message: '确定要删除这条数据吗?',
  });

  if (confirmed) {
    console.log('执行删除');
  }
};

✅ 适用场景:表单提交确认、登录弹窗、选择器等需要“等待用户反馈”的交互。


✅ 使用方式三:模板式渲染(传统风格)

将 Modal 当作普通组件插入 JSX 中,但仍受 nice-modal-react 管理。

import React from 'react';
import { NiceModal } from 'nice-modal-react';
import MyModal from './components/MyModal';

const App = () => {
  return (
    <div>
      {/* 渲染指定 ID 的 modal */}
      <NiceModal id={MyModal.id} title="来自模板" />

      {/* 或者多个参数 */}
      <NiceModal id={MyModal.id} {...{ title: '动态标题' }} />
    </div>
  );
};

✅ 适用场景:

  • SSR(服务端渲染)
  • 需要在特定位置渲染 modal
  • 与某些 UI 框架深度集成时

⚠️ 注意:仍需先用 niceModal() 包装组件。


✅ 使用方式四:动态内联 Modal(无需定义组件)

直接在事件中创建一个临时的匿名 Modal。

import React from 'react';
import { show } from 'nice-modal-react';

const App = () => {
  const openInline = () => {
    show(
      ({ visible, hide }) => {
        return visible ? (
          <div style={{ ...overlayStyle }}>
            <div style={{ ...contentStyle }}>
              <h3>内联 Modal</h3>
              <p>这是即时创建的弹窗</p>
              <button onClick={hide}>关闭</button>
            </div>
          </div>
        ) : null;
      },
      { id: 'temp-modal' } // 可选唯一标识
    );
  };

  return <button onClick={openInline}>打开内联 Modal</button>;
};

✅ 优点:适合调试、快速原型、一次性弹窗。


🔧 全局控制 API

nice-modal-react 提供了一些全局控制方法,用于管理所有 modal 实例。

方法说明
show(Component, props)显示某个 modal
hide(id)隐藏指定 modal
remove(id)销毁指定 modal
clear()关闭并销毁所有 modal
visibleModals获取当前所有可见 modal 的数组

示例:

import { hide, clear, visibleModals } from 'nice-modal-react';

// 关闭某个 modal
hide(MyModal.id);

// 清空所有 modal
clear();

// 查看当前激活的 modals
console.log(visibleModals); // [{ id, component, props }]

🔄 Modal ID 说明

每个被 niceModal() 包装的组件都会自动生成一个唯一的 id(通常是组件名或手动指定)。

你也可以手动指定:

const MyModal = niceModal(() => { ... }, 'my-custom-id');
console.log(MyModal.id); // "my-custom-id"

💡 最佳实践建议

场景推荐方式
普通弹窗(提示、通知)函数式调用 + show()
确认对话框、登录框await show(...) 异步模式
复杂交互逻辑useModal() 自定义控制
快速调试 / 临时弹窗内联 Modal
SSR 或静态布局模板式 <NiceModal id={...} />

🎨 样式建议(CSS 示例)

.modal-overlay {
  position: fixed;
  top: 0; left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal-content {
  background: white;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  max-width: 400px;
  text-align: center;
}

📚 参考资源


❓ 常见问题

Q: 为什么 modal 不显示?

A: 检查是否遗漏 <NiceModalProvider>,或未使用 niceModal() 包装组件。

Q: 如何防止重复打开同一个 modal?

A: nice-modal-react 默认允许叠加。若需单例,可在业务层加锁判断,或使用 hide/remove 控制。

Q: 能否和 Ant Design Modal 结合?

A: 可以!后续可提供示例(如封装 Modal.confirm 风格)。


📝 附录:TypeScript 支持示例

// components/TypedModal.tsx
import React from 'react';
import { useModal } from 'nice-modal-react';

interface Props {
  title: string;
  onOk?: () => void;
}

const TypedModal: React.FC<Props> = ({ title, onOk }) => {
  const { visible, hide } = useModal();

  return visible ? (
    <div className="modal">
      <h3>{title}</h3>
      <button onClick={() => { onOk?.(); hide(); }}>确定</button>
      <button onClick={hide}>取消</button>
    </div>
  ) : null;
};

export default niceModal(TypedModal);

如有需要,还可提供:

  • Ant Design 集成示例
  • Redux/Saga 中调用 modal
  • 多语言支持方案
  • 动画过渡效果处理

欢迎继续提问!💡