API 参考

react-snappy-modal 1.2 导出的全部内容,以及每个调用的确切行为。

导出内容

默认导出是带有静态方法的 SnappyModal 类。Provider 和 Hook 是具名导出。

tsx
1import SnappyModal, {
2  SnappyModalProvider,
3  useCurrentModal,
4  useSnappyModalState,
5} from 'react-snappy-modal';

SnappyModal.show(component, options?)

将 component 渲染为新的模态框,并返回在该模态框关闭时完成的 Promise<any>。每次调用都会创建一个拥有唯一 modalId 的新模态框;如果已有模态框打开,新模态框会叠加在上面,而不是替换它。

options 会合并到下方选项表的默认值之上。

tsx
1const result = await SnappyModal.show(<MyModal />, { layer: 1 });

SnappyModal.close(value?, layerOrId = 0)

关闭一个模态框,并以 value resolve 其 Promise。layerOrId 用于选择目标:数字(或数字字符串)视为层级,其他值视为 modalId。默认是层级 0。

如果目标层级上有多个模态框,关闭的是该层级中最早打开的那个,而不是最新的。没有匹配的模态框时什么也不做,也不会报错。

tsx
1SnappyModal.close('done');          // first modal on layer 0
2SnappyModal.close('done', 1);       // first modal on layer 1
3SnappyModal.close('done', modalId); // one specific modal

SnappyModal.throw(error?, layerOrId = 0)

与 close() 相同,但以 error reject Promise。仅在调用方需要把结果当作失败处理时使用,并始终配合 try/catch,否则会被报告为未处理的 rejection。

tsx
1try {
2  await SnappyModal.show(<UploadModal />);
3} catch (error) {
4  // SnappyModal.throw(new Error('Upload failed')) lands here
5}

SnappyModal.isShow()

至少有一个模态框打开时返回 true。它只读取一次状态,不会触发重新渲染。需要响应变化的组件请使用 useSnappyModalState()。

tsx
1if (!SnappyModal.isShow()) {
2  SnappyModal.show(<Welcome />);
3}

useCurrentModal()

只能在由 show() 渲染的组件内使用。返回 resolveModal(value)、rejectModal(error),以及该模态框的 layer 和 modalId。

resolveModal 和 rejectModal 按 ID 关闭渲染它们的那个模态框,因此即使同一层级有多个模态框也能准确关闭。在模态框组件内应优先使用它们,而不是静态方法。

tsx
1function Confirm() {
2  const { resolveModal, rejectModal, layer, modalId } = useCurrentModal();
3  return <button onClick={() => resolveModal(true)}>OK</button>;
4}

useSnappyModalState()

订阅模态框栈,并在模态框打开或关闭时重新渲染。有模态框打开时 isShow 为 true;modalProgress 按渲染顺序列出已打开的模态框,每项包含 modalId 和合并后的 options。

tsx
1function ModalCount() {
2  const { isShow, modalProgress } = useSnappyModalState();
3  return isShow ? <span>{modalProgress.length} open</span> : null;
4}

<SnappyModalProvider>

在 children 之后渲染所有已打开的模态框,并应用滚动锁定。在应用根部附近挂载且只挂载一次。

tsx
1<SnappyModalProvider>
2  <App />
3</SnappyModalProvider>

选项

选项作为 show() 的第二个参数传入。每个模态框都有自己的选项。

选项类型默认值说明
allowOutsideClickbooleantrue为 true 时,点击内容外部会关闭模态框,并以 undefined resolve Promise。在用户必须做出选择的流程中请设为 false。
allowScrollbooleanfalse为 false 时,模态框打开期间固定后面的页面,关闭时恢复滚动位置。只要任一已打开的模态框设置了 allowScroll: false,锁定就会保持。
backdropboolean | stringtruetrue 会使模态框后面的页面变暗,false 则去除遮罩。两种情况下全屏点击区域都存在,因此外部点击仍遵循 allowOutsideClick。
positionstring'center'内容在 3×3 网格中的位置:top-left、top-center、top-right、center-left、center、center-right、bottom-left、bottom-center、bottom-right 之一。
zIndexnumber1000模态框区域的 CSS z-index。省略时使用样式表默认值 1000。
layernumber0叠加分组。已打开的模态框按 layer 排序,层级越高越靠上渲染,并可通过 close(value, layer) 指定。
classNamestring-添加到内容包装器(.snappy-modal-content)的类名。
styleReact.CSSProperties-应用于内容包装器的内联样式。

自定义背景颜色

在 1.2.1 版本中,给 backdrop 传入字符串会设置 --snappy-modal-backdrop CSS 变量,但内置样式表读取的是 --snappy-modal-backdrop-color,因此颜色不会生效。请改为在 CSS 中直接设置颜色。

css
1.snappy-modal-area.backdrop {
2  --snappy-modal-backdrop-color: rgba(15, 23, 42, 0.8);
3}

layerOrId 的解析规则

close() 和 throw() 使用相同的规则查找目标。

  • 数字和数字字符串(如 1 或 "1")是层级,其他字符串是 modalId。
  • 省略该参数时以层级 0 为目标。
  • 指定层级时,选择该层级中最早打开的模态框。
  • 没有匹配的模态框时什么也不会发生。

为结果指定类型

show() 返回 Promise<any>。用一个小型泛型辅助函数包装它,调用方就能得到准确的结果类型。外部点击会无值 resolve,因此请在联合类型中保留 undefined。

tsx
1import type { ReactElement } from 'react';
2import SnappyModal from 'react-snappy-modal';
3
4type SnappyModalOptions = Parameters<typeof SnappyModal.show>[1];
5
6export function showModal<T>(
7  element: ReactElement,
8  options?: SnappyModalOptions,
9): Promise<T | undefined> {
10  return SnappyModal.show(element, options);
11}
12
13const confirmed = await showModal<boolean>(<Confirm />); // boolean | undefined
下一篇指南:异步确认模态框 →