跳到主要內容

常見問題

為什麼沒有 app.use() 安裝機制​

React 沒有 Vue 的外掛體系。@lh-ui/react 全部為命名匯出,按需引入即可,這也讓 tree-shaking 更友善。全域設定用 LhConfigProvider 元件包裹。

為什麼樣式不自動注入​

與 @lh-ui/vue2 對齊的按需策略:包入口不注入全量樣式 side-effect,由使用者顯式引入 @lh-ui/react/theme.css 與 @lh-ui/react/style/<name>。理由是 React 生態的按需引入是主流,且全量 side-effect 會破壞 tree-shaking。

為什麼 onChange 是兩個參數​

(value, event) 的雙參數設計與 lh-ui-plus 的 emit('change', [val, e]) 同構,方便從 Vue 遷移,也保留了取得原生事件的能力。

彈層定位為什麼不用 floating-ui​

家族紅線:彈層幾何計算在 @lh-ui/share/core/shared/popper 內實作,各端共享同一份邏輯與邊界處理(翻轉、溢出收起、箭頭)。引入第三方套件會造成各端行為漂移。

過渡動畫為什麼不用 react-transition-group​

同上。useTransition 是本庫自研的 mounted + phase 狀態機,類別名與 share SCSS 完全一致(*-enter-from / *-enter-active / *-enter-to),且 StrictMode 安全。

Dialog 為什麼是純受控​

open 完全由外部 state 持有,任何關閉路徑(遮罩點選 / Esc / 關閉按鈕)都只調 onClose。lh-ui-plus 內部有 isVisible 中間態 + watch 雙向同步,React 版去掉了這一層:受控語義更純粹,也避免了 props 與內部狀態競態。

多個 Dialog 同時開啟,Esc 為什麼只關一個​

useLhOverlayStack 維護開啟順序棧,Esc 只關棧頂彈層。這是 APG dialog pattern 的要求,避免一次按鍵把所有彈層一起帶走。

命令式服務會建立多個 React root 嗎​

不會。message 等服務共享一個惰性建立的單例容器 root,首次呼叫才建立並 append 到 body,元件內部 state 管理訊息佇列。destroyContainer() 顯式 root.unmount()。

在 SSR 裡呼叫 message 會怎樣​

只打一條開發告警並 no-op,不建立 DOM。DOM 操作全部在 useEffect / useIsomorphicLayoutEffect 內,useLhLocale 用 useSyncExternalStore 提供一致的 SSR 快照。

為什麼需要 forwardRef 而不直接用 ref prop​

支援 React 18 與 19 雙版本。React 19 的 ref-as-prop 在 18 上不存在,forwardRef 是兩個版本共同的超集。可聚焦元件(button / input / select / dialog / tooltip)都轉發 ref。

可以和 lh-ui-plus 在同一個專案裡用嗎​

可以,兩者類別名與令牌完全一致,樣式不衝突。但通常沒必要——它們是同一批元件的兩種框架形態。若在漸進遷移場景下混用,注意兩庫的 @lh-ui/share 版本範圍要相容。

首期有哪些未實作的​

P1/P2 元件(Popover、Drawer、Dropdown、Table 等)未實作。三個命令式服務 (message / notification / loading)均已完整實作。