@ebay/nice-modal-react

中文文档
1.2.13发布于 2023/10/03MITTypeScriptESM + CJS零依赖近 30 天下载 128.8万

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

中文使用文档
文档目录17 节
  1. 安装
  2. 创建您的模块组件
  3. 使用您的模块组件
  4. 嵌入您的应用程序 NiceModal.Provider 数字 :
  5. 按组件使用模式
  6. 通过 id 使用模式
  7. 用钩子模式
  8. 宣布您的模式而不是 register
  9. 使用承诺 API
  10. 与 Redux 合并
  11. 使用任何 UI 库
  12. 使用帮助方法
  13. API 参考
  14. 测试
  15. 贡献指南
  16. 财务问题
  17. 我能用一种模式在组件树上找到背景吗?

不错的莫达尔

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

您也可以在 eBay科技博客。 。 。 .

NPM Downloads Build Status Coverage Status Demo MIT licensed

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

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来注册模式,这样你不需要导入模式组件来使用:

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://ebay.github.io/nice-module-resact 互联网档案馆的存檔,存档日期2013-12-22

关键特性

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

动机

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

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

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

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

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

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

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

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

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

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

根据 维基百科,一种模式可以描述为:

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

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

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

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

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

使用量

安装

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

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

创建您的模块组件

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

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供应商,例如:

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

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

按组件使用模式

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

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 控制一个很好的模式 :

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 钩子不仅可以在模式组件内使用,也可以通过传递方式代号/组件来使用:

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用作普通组件,那么你不需要注册. 例如:

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

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

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工具来跟踪/调试模式的状态变化. 这是如何做到的:

// 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库提供的任何模式式组件.

使用帮助方法

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

//...
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提供了帮助方法.

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)}>

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

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

测试

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

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();
});

贡献指南

# 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 查看实例.

财务问题

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

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

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} />
    </>
  );
}

看见更多 这里。 。 。 .

许可证

麻省理工学院

版本与发布记录

@ebay/nice-modal-react 共发布 18 个版本,首次发布于 2021/08/27;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.2.13latest2023/10/033 年前
1.2.122023/10/023 年前
1.2.112023/09/293 年前
1.2.102023/04/093 年前
1.2.92023/03/033 年前
1.2.82022/10/214 年前

关于 @ebay/nice-modal-react 的常见问题

@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 和提交记录判断。