You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
No try/catch around the hook: useObjectTranslation is provider-safe (optional context read + react-i18next global-instance fallback), and wrapping a hook call in try/catch violates rules-of-hooks — a throw after the hook ran would desync hook order on the next render (same fix as objectui#2595/#2596; this factory closure just escaped the static lint).
从注释可以看出这是一路抄下来的:ImportWizard 写着 "Mirrors the pattern in ObjectGrid.tsx",plugin-timeline 写着 "Mirrors the createSafeTranslationHook pattern used by plugin-detail / plugin-list"。
Locks the fallback semantics of the safe-translation hooks AFTER the try/catch-around-hook removal (rules-of-hooks, objectui#2595/feat(kanban): default lane field honours the ADR-0085 stageField role #2596 class): with no I18nProvider mounted, consumers must still get English defaults — via the testKey probe / per-key detection, not via a caught throw.
问题
仓库已有官方的 provider-free 翻译机制
createSafeTranslation(defaults, testKey)(packages/i18n/src/useSafeTranslation.ts:13),8 个以上文件正常在用。但另有 9 个文件各自手写了一份语义等价的实现,并且全都把 hook 调用包在try/catch里:packages/plugin-detail/src/useDetailTranslation.ts:22createSafeTranslationHook(defaults, testKey)— 与官方同签名,内部函数甚至同名useSafeTranslationpackages/plugin-timeline/src/useTimelineTranslation.ts:46packages/plugin-list/src/ListView.tsx:285packages/plugin-calendar/src/CalendarView.tsx:93packages/plugin-grid/src/ObjectGrid.tsx:111packages/plugin-designer/src/hooks/useDesignerTranslation.ts:209packages/components/src/renderers/complex/data-table.tsx:161languagepackages/plugin-gantt/src/useGanttTranslation.ts:103language传给日期格式化packages/plugin-grid/src/ImportWizard.tsx:211为什么这是 bug,而不只是重复代码
官方实现的注释明确写了为什么不能用 try/catch:
也就是说 #2595/#2596 已经修过这一类缺陷,但只修到了
packages/i18n里的官方实现;这 9 份手写副本原样保留了它。它们躲过 lint 的原因也在注释里:工厂闭包让静态规则失效。从注释可以看出这是一路抄下来的:ImportWizard 写着 "Mirrors the pattern in ObjectGrid.tsx",plugin-timeline 写着 "Mirrors the createSafeTranslationHook pattern used by plugin-detail / plugin-list"。
前提已核实
去掉 try/catch 是安全的,两条证据:
useObjectTranslation(packages/i18n/src/provider.tsx:163)用的是可选 context 读取(context?.language || i18n.language || 'en'),不抛异常。对比紧邻其下的useI18nContext:186,那个才有if (!context) throw。packages/i18n/src/__tests__/useSafeTranslation.test.tsx的文件头注释把语义钉死了:建议做法
createSafeTranslation目前只从@object-ui/i18n导出,没有经@object-ui/react转出(而useSafeTranslate有,见packages/react/src/index.ts:27)。先补上这一行,plugin-timeline等就不必新增依赖。data-table/gantt需要language——可以给官方实现的返回值增补language(纯新增,不破坏现有调用方),这样它们也能收敛;ImportWizard的逐 key 兜底是真实差异,保留本地逻辑但去掉 try/catch。try { … useObjectTranslation() … } catch,否则这个模式会继续被复制第 10 次。与 i18n 覆盖问题的关系
这是 rules-of-hooks 缺陷,与 objectui#2871(手搓
startsWith('zh')绕开语言包)不同类,故单独跟踪。但建议先做这个:#2871 要动的文件与这 9 个有重叠,先收敛掉重复的 hook,再迁移文案,落点会干净很多。发现来源:排查 #2871 时,顺着 objectstack#3589 收尾的 i18n 审计查到。