# @ebay/nice-modal-react 中文文档

规范地址：https://npmcn.com/package/%40ebay/nice-modal-react/

版本：1\.2\.13
npm 元数据更新时间：2026-06-27T00:07:36.814Z
中文译文更新时间：2026-11-13T04:29:20.391Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40ebay/nice-modal-react
原文对照：https://npmcn.com/package/%40ebay/nice-modal-react/?lang=original
项目主页：https://github.com/eBay/nice-modal-react#readme
源码仓库：https://github.com/eBay/nice-modal-react

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：128 kB，12 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：react \>16\.8\.0，react-dom \>16\.8\.0
- 首次发布：2021-08-27T04:25:03.797Z
- 最新版本发布：2023-10-03T09:21:52.000Z
- 近 30 天下载量：1287880（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：18（近 12 个月 0 个）

## 中文简介

这是一种小而零的依赖性用途,可以自然地管理反应模式. 它利用上下文在全球持续保持模式状态,以便你能够很容易地通过模式成分或id来显示/隐藏一种模式.

## 安装

```sh
npm install @ebay/nice-modal-react
```

也可以使用：`pnpm add @ebay/nice-modal-react`、`yarn add @ebay/nice-modal-react`、`bun add @ebay/nice-modal-react`

## README

# 不错的莫达尔

这是一种小而零的依赖性用途,可以自然地管理反应模式. 它利用上下文在全球持续保持模式状态,以便你能够很容易地通过模式成分或id来显示/隐藏一种模式.

> 您也可以在 [eBay科技博客](https://medium.com/ebaytech/rethink-modals-management-in-react-cf3b6804223d)。 。 。 .

[![NPM](https://img.shields.io/npm/v/@ebay/nice-modal-react.svg)](https://www.npmjs.com/package/@ebay/nice-modal-react) [![Downloads](https://img.shields.io/npm/dm/@ebay/nice-modal-react.svg)](https://www.npmjs.com/package/@ebay/nice-modal-react) [![Build Status](https://api.travis-ci.com/eBay/nice-modal-react.svg?branch=main)](https://app.travis-ci.com/github/eBay/nice-modal-react) [![Coverage Status](https://codecov.io/gh/ebay/nice-modal-react/branch/main/graph/badge.svg)](https://codecov.io/github/eBay/nice-modal-react) [![Demo](https://img.shields.io/badge/demo-link-orange.svg)](https://ebay.github.io/nice-modal-react/) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/eBay/nice-modal-react/blob/main/LICENSE.md)

例如,您可以使用下面的代码在任何地方显示一个模式:

```jsx
import NiceModal from '@ebay/nice-modal-react';
import MyModal from './MyModal';

//...
NiceModal.show(MyModal, { someProp: 'hello' }).then(() => {
  // do something if the task in the modal finished.
});
//...
```

或者你可以用一个ID来注册模式,这样你不需要导入模式组件来使用:

```jsx
import NiceModal from '@ebay/nice-modal-react';
import MyModal from './MyModal';

NiceModal.register('my-modal', MyModal);

// you can use the string id to show/hide the modal anywhere
NiceModal.show('my-modal', { someProp: 'hello' }).then(() => {
  // do something if the task in the modal finished.
});
//...

```

**页:1**数字 : `@ebay/nice-modal-react` 不是一个反应模式组件,但应该与UI 库等其他模式/对话框一起使用 [材料界面](https://material-ui.com/), (中文(简体) ), [蚂蚁. 设计](https://ant.design/), (中文(简体) ), [启动陷阱反应](https://react-bootstrap.github.io/)等 (中文(简体) ).

# 实例

您可以在 : [https://ebay.github.io/nice-module-resact 互联网档案馆的存檔,存档日期2013-12-22](https://ebay.github.io/nice-modal-react)

# 关键特性

-   零依赖和小:~2kb gzip后.
-   无所控制. 您可以在模式组件中关闭模式本身 .
-   解脱相. 无需导入模式组件即可使用. Modals可以通过id管理.
-   您模式组件的代码如果是隐形的,则不执行 .
-   它不会打破显示/隐藏模式的过渡.
-   承诺基于。 除了使用道具从母元件中与模式进行交互外,通过承诺也可以更容易地实现.
-   容易与任何UI库集成.

# 动机

在React中使用模式有点让人沮丧. 如果您需要执行以下 UI :

![](https://npmcn.com/package/%40ebay/nice-modal-react/images/modal-example.jpg)

该对话框用于创建 JIRA 票. 它可以从许多地方显示,从头到上下文菜单,到列表页面. 传统上,我们申报了带有JSX标签的模式组件。 但问题就变成了“我们应该在哪里申报标签?”

最常见的选择是,无论它在哪里使用,都予以宣布。 但使用模式来宣示,不仅涉及JSX标签,也涉及维持模式状态,如能见度,集装箱组件中的参数。 逐一宣布意味着管理着各地的国家. 令人沮丧.

另一种选择将其置于Root组件中,例如:

```jsx
const Root = () => {
  const [visible, setVisible] = useState(false);
  // other logic ...
  return (
    <>
      <Main />
      <NewTicketModal visible={visible} />
    </>
  );
}
```

然而,当您在根组件中声明模式时,还存在一些问题:

1.  不可伸缩. 在根构件中保持模式状态是不合理的. 当您需要更多模式时, 您需要保持许多状态, 特别是您需要为模式保持参数 .
2.  很难从儿童成分中显示或隐藏模式. 当你在一个组件中保持状态时,你需要通过 `setVisible` 到需要展示或隐藏模式的地方。 事情太复杂了.

不幸的是,大多数使用模式的例子只是遵循了这种做法,在React中管理模式时造成了这样的混乱.

我认为,你必须曾经遇到这样的情景,原来你只需要在点击按钮时显示一个模式,然后当要求发生变化时,你需要从另一个地方打开同一个模式。 那你必须重构你的代码 重新考虑在哪里宣布模式。 造成这种烦恼的根源仅仅是因为我们不了解一种模式的本质.

# 在反应中重新思考 Modal 使用模式

根据 [维基百科](https://en.wikipedia.org/wiki/Modal_window),一种模式可以描述为:

> 用于阻止用户与您的应用程序互动直到关闭窗口的窗口.

从定义中我们可以得出一个结论:一种模式是一个全球观点,它不一定与特定的上下文相关.

这与单页UI应用程序中的页面概念非常相近. 模式的能见度/状态应在全球范围内加以管理,因为从UI的角度来看,模式可以在任何页面/组件之上显示。 模式和页面的唯一区别是:一种模式允许您不离开当前页面去完成一些单独的任务.

对于页面管理,我们已经有像React Router这样的路由器框架,它帮助通过URL导航到一页. 实际上,您可以认为URL是一页的全球ID. 所以,同样,如果你给一个模式分配一个uniq id,然后由id显示/隐藏它呢? 我们就是这么设计的 Nice Modal.

然而,NiceModal除了使用id外,还允许直接使用模式组件来管理.

# 使用量

## 安装

```bash
# with yarn
yarn add @ebay/nice-modal-react

# or with npm
npm install @ebay/nice-modal-react
```

## 创建您的模块组件

使用 NiceModal 可以很容易地创建单独的模式组件 。 这和你创造一个正常的组件一样 但用高音量来包装它 `NiceModal.create`。例如,下面的代码显示如何创建对话框 [蚂蚁. 设计](https://ant.design/)数字 :

```jsx
import { Modal } from 'antd';
import NiceModal, { useModal } from '@ebay/nice-modal-react';

export default NiceModal.create(({ name }) => {
  // Use a hook to manage the modal state
  const modal = useModal();
  return (
    <Modal
      title="Hello Antd"
      onOk={() => modal.hide()}
      visible={modal.visible}
      onCancel={() => modal.hide()}
      afterClose={() => modal.remove()}
    >
      Hello {name}!
    </Modal>
  );
});
```

从代码来看,我们可以看到:

-   模式不受控制。 您可以将您的模式隐藏在组件中, 不管它显示在哪里 .
-   由 `NiceModal.create` 确保组件在可见之前不会被执行.
-   你可以打电话 `modal.remove` 从 React 组件树去除您的模式组件到保留过渡.

接下来,让我们看看如何使用模式.

## 使用您的模块组件

有非常灵活的API供您管理模式. 见下文导言.

### 嵌入您的应用程序 `NiceModal.Provider`数字 :

由于我们将在全球管理模式状态,第一件事就是将您的应用程序嵌入NiceModal供应商,例如:

```js
import NiceModal from '@ebay/nice-modal-react';
ReactDOM.render(
  <React.StrictMode>
    <NiceModal.Provider>
      <App />
    </NiceModal.Provider>
  </React.StrictMode>,
  document.getElementById('root'),
);
```

提供者会使用React上下文来保持所有模式状态.

### 按组件使用模式

您可以通过组件本身控制一个很好的模式 .

```js
import NiceModal from '@ebay/nice-modal-react';
import MyAntdModal from './my-antd-modal'; // created by above code

function App() {
  const showAntdModal = () => {
    // Show a modal with arguments passed to the component as props
    NiceModal.show(MyAntdModal, { name: 'Nate' })
  };
  return (
    <div className="app">
      <h1>Nice Modal Examples</h1>
      <div className="demo-buttons">
        <button onClick={showAntdModal}>Antd Modal</button>
      </div>
    </div>
  );
}
```

### 通过 id 使用模式

您也可以通过 id 控制一个很好的模式 :

```js
import NiceModal from '@ebay/nice-modal-react';
import MyAntdModal from './my-antd-modal'; // created by above code

// If use by id, need to register the modal component.
// Normally you create a modals.js file in your project
// and register all modals there.
NiceModal.register('my-antd-modal', MyAntdModal);

function App() {
  const showAntdModal = () => {
    // Show a modal with arguments passed to the component as props
    NiceModal.show('my-antd-modal', { name: 'Nate' })
  };
  return (
    <div className="app">
      <h1>Nice Modal Examples</h1>
      <div className="demo-buttons">
        <button onClick={showAntdModal}>Antd Modal</button>
      </div>
    </div>
  );
}
```

### 用钩子模式

这个 `useModal` 钩子不仅可以在模式组件内使用,也可以通过传递方式代号/组件来使用:

```jsx
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import MyAntdModal from './my-antd-modal'; // created by above code

NiceModal.register('my-antd-modal', MyAntdModal);
//...
// if use with id, need to register it first
const modal = useModal('my-antd-modal');
// or if with component, no need to register
const modal = useModal(MyAntdModal);

//...
modal.show({ name: 'Nate' }); // show the modal
modal.hide(); // hide the modal
//...
```

### 宣布您的模式而不是 `register`

你创造的优雅模式组件也可以被JSX用作普通组件,那么你不需要注册. 例如:

```jsx
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import MyAntdModal from './my-antd-modal'; // created by above code

function App() {
  const showAntdModal = () => {
    // Show a modal with arguments passed to the component as props
    NiceModal.show('my-antd-modal')
  };
  return (
    <div className="app">
      <h1>Nice Modal Examples</h1>
      <div className="demo-buttons">
        <button onClick={showAntdModal}>Antd Modal</button>
      </div>
      <MyAntdModal id="my-antd-modal" name="Nate" />
    </div>
  );
}
```

有了这个方法,你可以得到优雅:

-   继承 在某些组件节点下的模式组件中发生上下文 .
-   通过道具将参数传递到模式组件.

> 注:如果以 id 方式显示组件,但模式不宣布或登记。 只会在Dev控制台发出警告.

### 使用承诺 API

除了使用道具从母元件中与模式进行交互外,通过承诺也可以更容易地实现. 例如,我们有一个用户列表页面,其中包含一个添加用户按钮,以显示一个对话框来添加用户. 在用户被添加后,列表应该刷新自己以反映变化,然后我们可以使用下面的代码:

```jsx
NiceModal.show(AddUserModal)
  .then(() => {
    // When call modal.resolve(payload) in the modal component
    // it will resolve the promise returned by `show` method.
    // fetchUsers will call the rest API and update the list
    fetchUsers()
  })
  .catch(err=> {
    // if modal.reject(new Error('something went wrong')), it will reject the promise
  }); 
```

您可以在代码和框上看到现场实例.

### 与 Redux 合并

尽管没有必要,但可以集成Redux来管理好模式状态. 然后可以使用Redux dev工具来跟踪/调试模式的状态变化. 这是如何做到的:

```jsx
// First combine the reducer
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';
import NiceModal from '@ebay/nice-modal-react';
import { Button } from 'antd';
import { MyAntdModal } from './MyAntdModal';
import logger from 'redux-logger';

const composeEnhancers = (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
const enhancer = composeEnhancers(applyMiddleware(logger));

const store = createStore(
  combineReducers({
    modals: NiceModal.reducer,
    // other reducers...
  }),
  enhancer,
);

// Passing Redux state to the nice modal provider
const ModalsProvider = ({ children }) => {
  const modals = useSelector((s) => s.modals);
  const dispatch = useDispatch();
  return (
    <NiceModal.Provider modals={modals} dispatch={dispatch}>
      {children}
    </NiceModal.Provider>
  );
};

export default function ReduxProvider({ children }) {
  return (
    <Provider store={store}>
      <ModalsProvider>{children}</ModalsProvider>
    </Provider>
  );
}
```

### 使用任何 UI 库

NiceModal提供生命囊方法来管理模式状态. 您可以使用模式处理器返回 `useModal` 钩子将任何类似组件的模式绑入状态。 以下是您将使用的典型状态和方法:

-   **模式. 可见**:一种模式的能见度.
-   **模式. hide**:将隐藏模式,即更改 `modal.visible` 以假相报.
-   **模式. 移动**: 从树上去除模式组件, 以便您模式的代码在不可见时不被执行 。 通常在模式的过渡后称为这种方法.
-   **模式. 保持流动** 如果您不想在某些情况下从树上移除模式, 您可以决定是否调用 `modal.remove` 基于数值 `keepMounted`。 。 。 .

基于这些属性/方法,您可以轻松地使用由任何UI库提供的任何模式式组件.

### 使用帮助方法

如你所见,我们使用类似下面的代码来管理模式状态:

```jsx
//...
const modal = useModal();
return (
  <Modal
    visible={modal.visible}
    title="Hello Antd"
    onOk={() => modal.hide()}
    onCancel={() => modal.hide()}
    afterClose={() => modal.remove()}
  >
    Hello NiceModal!
  </Modal>
);
//...
```

它的束缚 `visible` 属性 `modal` 处理器,和使用 `modal.hide` 来隐藏关闭按钮时的模式。 在接近过渡后,它呼唤 `modal.remove` 从多姆节点中删除模式.

对于每一个模式的实施,我们总是需要用人工方式进行这些约束。 因此,为了更容易使用,我们为3个受欢迎的UI库材料UI,Ant.Design和Bootstrap React提供了帮助方法.

```jsx
import NiceModal, {
  muiDialog,
  muiDialogV5,
  antdModal,
  antdModalV5,
  antdDrawer,
  antdDrawerV5,
  bootstrapDialog
} from '@ebay/nice-modal-react';

//...
const modal = useModal();
// For MUI
<Dialog {...muiDialog(modal)}>

// For MUI V5
<Dialog {...muiDialogV5(modal)}>

// For ant.design
<Modal {...antdModal(modal)}>

// For ant.design v4.23.0 or later
<Modal {...antdModalV5(modal)}>

// For antd drawer
<Drawer {...antdDrawer(modal)}>

// For antd drawer v4.23.0 or later
<Drawer {...antdDrawerV5(modal)}>

// For bootstrap dialog
<Dialog {...bootstrapDialog(modal)}>

```

这些帮助者将约束模式的共同行动来纠正组件的属性. 然而,您总是可以在帮助者财产之后推翻财产。 例如:

```jsx
const handleSubmit = () => {
  doSubmit().then(() => {
    modal.hide();
  });
}
<Modal {...antdModal(modal)} onOk={handleSubmit}>
```

举例来说 `onOk` 属性将覆盖来自 `antdModal` 帮手.

## API 参考

[https://ebay.github.io/nice-module-react/api/ 互联网档案馆的存檔,存档日期2013-12-02](https://ebay.github.io/nice-modal-react/api/)

## 测试

你可以用工具测试你漂亮的模式 `@testing-library/react`。 。 。 .

```jsx
import NiceModal from '@ebay/nice-modal-react';
import { render, act, screen } from '@testing-library/react';
import { MyNiceModal } from '../MyNiceModal';

test('My nice modal works!', () => {
  render(<NiceModal.Provider />
  
  act(() => {
    NiceModal.show(MyNiceModal);
  });
  
  expect(screen.getByRole('dialog')).toBeVisible();
});
```

## 贡献指南

```bash
# 1. Clone repo
git clone https://github.com/eBay/nice-modal-react.git

# 2. Install deps
cd nice-modal-react
yarn

# 3. Make local repo as linked
yarn link

# 4. Start dev server
yarn dev

# 5. Install examples deps
cd example
yarn

# 6. Use local linked lib
yarn link @ebay/nice-modal-react

# 7. Start examples dev server
yarn start
```

然后您可以访问 http://localhost: 3: 00 查看实例.

## 财务问题

### 我能用一种模式在组件树上找到背景吗?

对 要从组件树的上下文中获取数据,需要使用声明方式. 例如:

```jsx
export default function AntdSample() {
  return (
    <>
      <Button type="primary" onClick={() => NiceModal.show('my-antd-modal', { name: 'Nate' })}>
        Show Modal
      </Button>
      <MyAntdModal id="my-antd-modal" {...otherProps} />
    </>
  );
}
```

看见更多 [这里](https://github.com/eBay/nice-modal-react/issues/104)。 。 。 .

# 许可证

麻省理工学院

## 常见问题

### @ebay/nice-modal-react 是什么？

这是一种小而零的依赖性用途,可以自然地管理反应模式\. 它利用上下文在全球持续保持模式状态,以便你能够很容易地通过模式成分或id来显示/隐藏一种模式\.

### 如何安装 @ebay/nice-modal-react？

在项目目录运行 npm install @ebay/nice-modal-react，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（\>16\.8\.0）、react-dom（\>16\.8\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @ebay/nice-modal-react 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @ebay/nice-modal-react 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @ebay/nice-modal-react 可以商用吗？

@ebay/nice-modal-react 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @ebay/nice-modal-react 的下载量有多少？

根据 npm 官方下载统计，@ebay/nice-modal-react 在 2026/10/13 – 2026/11/11 这 30 天内被下载 1,287,880 次，日均约 42,929 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @ebay/nice-modal-react 还在维护吗？

最新版本 1\.2\.13 发布于 2023/10/03（3 年前）；至今共发布 18 个版本，其中过去 12 个月发布了 0 个；首次发布于 2021/08/27。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

