npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

async-modal-render

v0.1.3

Published

A lightweight library that promisifies React modal operations, allowing elegant handling of modal interactions using async/await syntax

Readme

async-modal-render

npm version license

一个将 React 模态框操作 Promise 化的轻量级工具库,让你可以使用 async/await 语法优雅地处理模态框交互。

使用文档

为什么需要 async-modal-render?

传统 Modal 的痛点

在传统的 Modal 使用方式中,我们需要通过回调函数来处理用户的操作,这导致代码逻辑分散,难以维护:

// ❌ 传统方式:代码逻辑分散,难以阅读
function TraditionalWay() {
  const [visible, setVisible] = useState(false);

  const handleClick = () => {
    setVisible(true);
  };

  // 确认的回调逻辑 - 分散在另一个地方
  const handleOk = async (formData) => {
    try {
      await api.submit(formData);
      message.success('提交成功');
    } catch (error) {
      message.error('提交失败');
    } finally {
      setVisible(false);
    }
  };

  // 取消的回调逻辑 - 又在另一个地方
  const handleCancel = () => {
    setVisible(false);
  };

  return (
    <>
      <Button onClick={handleClick}>打开弹窗</Button>
      <Modal visible={visible} onOk={handleOk} onCancel={handleCancel}>
        <Form />
      </Modal>
    </>
  );
}

async-modal-render 的优势

使用 async-modal-render,代码逻辑集中在一处,清晰易懂:

import { asyncModalRender, AsyncModalRenderCancelError } from 'async-modal-render';

// ✅ async-modal-render 方式:逻辑集中,代码清晰
function AsyncModalWay() {
  const handleClick = async () => {
    try {
      // 弹窗逻辑、确认逻辑、后续处理都在一起
      const formData = await asyncModalRender(FormModal, { title: '填写表单' });

      // 用户点击确认后才会执行到这里
      await api.submit(formData);
      message.success('提交成功');

      // 继续后续操作
    } catch (error) {
      // 用户点击取消或发生错误都会进入这里
      if (error instanceof AsyncModalRenderCancelError) {
        console.log('用户取消了操作');
      } else {
        message.error('提交失败');
      }
    }
  };

  return <Button onClick={handleClick}>打开弹窗</Button>;
}

对比总结

| 特性 | 传统 Modal | async-modal-render | |------|-----------|-----------------| | 代码组织 | 回调函数分散在多处 | async/await 集中处理 | | 可读性 | 需要跳转查看不同回调 | 从上到下线性阅读 | | 流程控制 | 需要状态管理 | Promise 自然流转 | | 错误处理 | 分散在各个回调 | try/catch 统一处理 | | 异步操作 | 回调嵌套 | async/await 扁平化 |

特性

  • 🎯 Promise 化:使用 async/await 处理模态框操作
  • 🪶 轻量级:最小依赖,体积小
  • 📦 TypeScript:完整的 TypeScript 支持
  • ⚛️ React:支持 React 16.8+
  • 🔧 灵活:兼容任何模态框组件库(Ant Design、Material-UI 等)

安装

npm install async-modal-render

yarn add async-modal-render

pnpm add async-modal-render

示例

// ========== 创建一个模态框组件 ==========
function ConfirmModal({ onOk, onCancel, message }) {
  return (
    <div className="modal">
      <p>{message}</p>
      <button onClick={() => onOk('confirmed')}>确认</button>
      <button onClick={onCancel}>取消</button>
    </div>
  );
}

// ========== 在任何地方使用 async/await 调用 ==========
import { asyncModalRender, AsyncModalRenderCancelError } from 'async-modal-render';

async function deleteUser(userId) {
  try {
    // 等待用户确认
    const result = await asyncModalRender(ConfirmModal, {
      message: '确定要删除这个用户吗?'
    });

    // 用户点击了确认,继续执行
    await api.delete(`/users/${userId}`);
    message.success('删除成功!');
  } catch (error) {
    // 用户点击了取消或关闭了弹窗
    if (error instanceof AsyncModalRenderCancelError) {
      message.info('已取消');
    }
    // 其它错误
  }
}

就是这么简单!不需要状态管理,不需要回调地狱,只需要简单的 async/await 流程。

更多用法见:文档

TODO

  • [x] useAsyncModalRenderContextrender / renderFactoryAsyncModalRenderOptions 添加 destroyStrategy?: 'hook' | 'context'
    • hook: useAsyncModalRenderContext 当前组件卸载后销毁
    • context: useAsyncModalRenderContext 当前组件卸载后不销毁, 随着 AsyncModalRenderProvider 销毁
  • [x] UseAsyncModalRenderReturn 添加一个 renderQuiet/renderSafe 函数。此函数在 onCancel 时不抛出错误,直接返回 undefined
  • [ ] 支持类组件的 Context 环境调用