開源專案
GSTJ/react-native-magic-modal avatar
GSTJ/react-native-magic-modal

可在 React Native、Expo 和 Web 中等候的模態框

可以從任何地方強制呼叫的模態庫。輕鬆控制模式、簡化複雜流程並創造可靠的使用者體驗。

644 個 Star16 個 ForkTypeScriptMIT

秒懂

它是什麼?
掛載一個 portal,呼叫 magicModal.show(),即可在 Expo、React Native 或 Web 上等候型別化的關閉結果。
適合誰用?
Magic Modal 為 React Native、Expo 和 Web 提供了基於 Promise 的模態框 API。README 記錄了 portal、型別化關閉結果以及各平台的安裝步驟。
可以商用嗎?
可以。MIT 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
還在維護嗎?
有在維護。儲存庫最近一次提交在 2 天前。
用什麼語言寫的?
主要是 TypeScript(依據 GitHub 的語言統計)。

以上回答依據專案的 GitHub 資料(最近同步於 2026年9月14日)與我們的分析,不構成法律意見。

開源專案深度解析

react-native-magic-modal|從任意非同步流程等候模態框

Magic Modal 是一個 TypeScript 庫,它讓模態框對話框表現得像一個可等候的 Promise。你掛載一個 portal,呼叫 magicModal.show() 並傳入元件和設定,傳回的句柄會在模態框關閉時解析。解析結果帶有模態框提交的資料,或者關閉的原因。README 將其描述為一種在 Expo、React Native 或 Web 上從任意非同步流程開啟模態框的方式,並且三者使用相同的型別化結果契約。

第1項專案核對:react-native-magic-modal 的檢查不能只看功能名稱。使用者應確認作業系統、執行時版本、輸入格式和權限邊界,再依 README 入口建立最小案例。對 GSTJ/react-native-magic-modal 而言,採用時要在 React Native 專案中檢查 `MagicModal` 的 provider、show/hide 呼叫與 modal component props,並觀察 Android、iOS 的返回鍵與動畫結果;README 沒說明的原生相容性不作推論。 先觀察命令是否接受輸入,再檢查輸出檔案、終端訊息、服務狀態或備份內容是否符合文件描述。若結果不同,保留完整錯誤、版本與設定,不把一次成功寫成相容性承諾。實際採用還要看失敗後如何恢復,README 沒有提供的行為應標成未知,交由原始碼、issue 或發布記錄補查。

第2項專案核對:react-native-magic-modal 的檢查不能只看功能名稱。使用者應確認作業系統、執行時版本、輸入格式和權限邊界,再依 README 入口建立最小案例。對 GSTJ/react-native-magic-modal 而言,採用時要在 React Native 專案中檢查 `MagicModal` 的 provider、show/hide 呼叫與 modal component props,並觀察 Android、iOS 的返回鍵與動畫結果;README 沒說明的原生相容性不作推論。 先觀察命令是否接受輸入,再檢查輸出檔案、終端訊息、服務狀態或備份內容是否符合文件描述。若結果不同,保留完整錯誤、版本與設定,不把一次成功寫成相容性承諾。實際採用還要看失敗後如何恢復,README 沒有提供的行為應標成未知,交由原始碼、issue 或發布記錄補查。

第3項專案核對:react-native-magic-modal 的檢查不能只看功能名稱。使用者應確認作業系統、執行時版本、輸入格式和權限邊界,再依 README 入口建立最小案例。對 GSTJ/react-native-magic-modal 而言,採用時要在 React Native 專案中檢查 `MagicModal` 的 provider、show/hide 呼叫與 modal component props,並觀察 Android、iOS 的返回鍵與動畫結果;README 沒說明的原生相容性不作推論。 先觀察命令是否接受輸入,再檢查輸出檔案、終端訊息、服務狀態或備份內容是否符合文件描述。若結果不同,保留完整錯誤、版本與設定,不把一次成功寫成相容性承諾。實際採用還要看失敗後如何恢復,README 沒有提供的行為應標成未知,交由原始碼、issue 或發布記錄補查。

第4項專案核對:react-native-magic-modal 的檢查不能只看功能名稱。使用者應確認作業系統、執行時版本、輸入格式和權限邊界,再依 README 入口建立最小案例。對 GSTJ/react-native-magic-modal 而言,採用時要在 React Native 專案中檢查 `MagicModal` 的 provider、show/hide 呼叫與 modal component props,並觀察 Android、iOS 的返回鍵與動畫結果;README 沒說明的原生相容性不作推論。 先觀察命令是否接受輸入,再檢查輸出檔案、終端訊息、服務狀態或備份內容是否符合文件描述。若結果不同,保留完整錯誤、版本與設定,不把一次成功寫成相容性承諾。實際採用還要看失敗後如何恢復,README 沒有提供的行為應標成未知,交由原始碼、issue 或發布記錄補查。

react-native-magic-modal|portal 擁有模態框堆疊

該庫的架構以 MagicModalPortal 為中心,它擁有模態框堆疊。每次呼叫 magicModal.show() 都會向該堆疊推入一個新條目,並傳回一個可等候的句柄。該句柄本身就是 Promise,同時還帶有該條目的 modalID、update 函數和 hide 函數。README 指出句柄上的 promise 別名已被棄用,因此你仍然可以寫 const { promise } = magicModal.show(...),但句柄本身就是 Promise。由於每個堆疊條目都保留自己的元件、設定、ID 和 Promise,第二次呼叫 show() 可以在目前模態框之上開啟,而不會混淆它們的結果。

react-native-magic-modal|安裝取決於平台

由於該套件為原生和瀏覽器執行時期提供了不同的入口,安裝命令有所不同。對於 Expo Web,README 列出了 pnpm add magic-modal,然後是 npx expo install react-native-gesture-handler react-native-reanimated react-native-worklets react-dom react-native-web @expo/metro-runtime。Expo iOS 和 Android 使用相同的第一條命令,但將 Web 依賴替換為 react-native-screens。對於僅瀏覽器的 React 應用(如 Next.js),整個安裝只需 pnpm add magic-modal;Web 入口沒有任何 React Native 依賴,因此不需要打包器別名或手勢或動畫對等依賴。README 還引導裸 React Native 使用者檢視單獨的安裝指南。

react-native-magic-modal|依環境掛載 portal

在 Expo 和原生 React Native 中,你需要將 MagicModalPortal 掛載在 GestureHandlerRootView 內部,如 README 範例所示。portal 與你的應用內容並排放置。對於 Expo Router,相同的結構放在根目錄的 app/_layout.tsx 中。對於瀏覽器應用,你只需在 Client Component 中掛載 portal,其他什麼都不用做;沒有 GestureHandlerRootView,因為瀏覽器套件不包含 Gesture Handler。README 指向 Next.js 指南以取得確切的 shell,以及 examples/next-web 中的可執行 App Router 消費範例。

react-native-magic-modal|型別化結果和關閉原因

API 對期望傳回的資料是泛型的。你使用 show<T>() 開啟模態框,並在模態框內容中使用 useMagicModal<T>() 呼叫 hide(data)。Promise 解析為 HideReturn<T>,其中包含原因,當原因是 MagicModalHideReason.INTENTIONAL_HIDE 時,還包含資料。其他原因包括背景按下、完成滑動、系統關閉(如 Android 返回鍵或 Web Escape)以及 hideAll()。TypeScript 會縮小結果型別,因此只有在檢查原因後才能存取 data。README 給出了一個確認模態框範例,呼叫方等候類似布林值的結果並據此操作,並指出瀏覽器入口渲染 DOM 元素而不是 React Native 元件,但使用相同的結果契約。

react-native-magic-modal|FAQ 說明了什麼

FAQ 回答了一些常見問題。多個模態框可以同時開啟,因為每次 show() 都會建立一個獨立的條目。模態框可以包含 ScrollView,但你必須透過傳入 swipeDirection: undefined 來停用滑動關閉;該庫不實作 snap points 或巢狀捲動。要從元件外部關閉模態框,請保留 show() 傳回的 modalID,並呼叫 magicModal.hide(undefined, { modalID })。在 iOS 上,要在原生選擇器下方渲染,你可以暫時呼叫 magicModal.disableFullWindowOverlay(),並在 finally 區塊中恢復。README 還連結到貢獻者清單和貢獻指南。

react-native-magic-modal|授權條款和貢獻

Magic Modal 以 MIT 授權條款發布,版權歸 Gabriel Taveira(2023)所有。該授權條款允許使用、複製、修改、合併、發布、分發、再授權和出售副本,前提是包含版權聲明。軟體按「原樣」提供,不提供任何形式的保證,授權條款不涉及支援、安全保證或生產就緒性。README 連結到貢獻者清單和貢獻指南,倉庫元資料顯示了一個未解決問題計數,但 README 沒有指定發布節奏或維護策略。

專案化核對:採用時要在 React Native 專案中檢查 `MagicModal` 的 provider、show/hide 呼叫與 modal component props,並觀察 Android、iOS 的返回鍵與動畫結果;README 沒說明的原生相容性不作推論。 這些觀察只針對 GSTJ/react-native-magic-modal README 已列出的行為;素材沒有交代的版本、平台或安全結果,保留為待確認事項。

編輯結論

Magic Modal 為 React Native、Expo 和 Web 提供了基於 Promise 的模態框 API。README 記錄了 portal、型別化關閉結果以及各平台的安裝步驟。專案採用 MIT 許可證,並包含文件、範例和貢獻指南的連結。 採用時要在 React Native 專案中檢查 `MagicModal` 的 provider、show/hide 呼叫與 modal component props,並觀察 Android、iOS 的返回鍵與動畫結果;README 沒說明的原生相容性不作推論。

官方來源

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
社群筆記

社群筆記