gt-react@10.12.0
概述
gt-react 现在导出一个 t() 函数,用于在浏览器中同步进行模块级字符串翻译。
此前,在 gt-react 中翻译字符串需要使用基于 React context 的钩子 (如 useGT) 。钩子在组件内部效果很好,但无法覆盖一种常见场景:在模块级别翻译字符串——也就是在 React 组件之外、在渲染之前、在普通工具文件中。
t() 正好填补了这一空白。它是一个同步函数,你可以在浏览器代码中的任何位置调用它:
import { t } from 'gt-react/browser';
const greeting = t('Hello, world!');无需钩子、无需异步处理,也无需组件树。
为什么采用这种方法
这个 PR 的核心思路,是尝试摆脱基于 React context 的翻译方式。通过在组件树之外运行,t() 可以支持更多有意思的模式——尤其是模块级翻译。字符串可以在定义它们的地方完成翻译,而不是等到渲染时再翻译。
这也带来了一些权衡:
- 仅限客户端。
t()仅适用于客户端 React 应用。它依赖浏览器中的模块执行机制,在 app 渲染前加载翻译。 - 切换语言需要整页重载。 由于翻译是在模块加载时解析的,切换 locale 需要重新执行这些模块——也就意味着必须整页刷新。无法在会话进行中热切换语言。
另一方面,开发者体验有了显著提升。不需要用钩子包装字符串,不需要组件级传递,也不需要处理异步边界——只需调用一个函数。
现有的 React context 方案 (useGT、<T> 等) 并不会消失。这只是为那些能够接受这些权衡的项目提供的一个额外选项。
工作原理
t() 会从预先加载好的翻译中同步解析出结果。这些翻译由 bootstrap() 填充;bootstrap() 是一个新的异步初始化函数,会在你的 app 渲染之前为当前 locale 加载所有翻译。
你需要修改你的 app 入口文件,先运行 bootstrap()。通常是 main.tsx,但你也可以在 index.html 中更改入口点。
// bootstrap.tsx(新入口点)
import gtConfig from '../gt.config.json';
import { bootstrap } from 'gt-react/browser';
async function getTranslations(locale: string) {
return import(`./_gt/${locale}.json`);
}
await bootstrap({
...gtConfig,
getTranslations,
});
await import('./main.tsx');getTranslations 函数是异步的——它会先加载翻译,然后再导入并执行 React 应用。这就是为什么 t() 能在模块级别访问到翻译:因为当任何模块调用 t() 时,翻译已经可用了。
这只适用于客户端 React 应用,因为模块级代码在浏览器中加载时会重新执行。而且由于我们需要重新执行模块来更新翻译后的内容,切换 locale 时需要整页重新加载。
实验性: 此功能目前仅适用于纯客户端 React 应用。
变量
t() 支持变量插值,用法与 msg() 相同:
import { t } from 'gt-react/browser';
t('Hello, {name}!', { name: 'John' }); // → "Hola, John!"适用场景
当你需要在 React 组件树之外使用翻译时,t() 是合适的选择——例如常量文件、工具函数、配置对象、路由定义,或任何在浏览器中于模块作用域执行的代码。
请注意:
- 这目前还无法与
gt-react系统的其余部分集成。 你需要完成上文所述的 bootstrap 设置。这是一种独立的方案。 - 仅限客户端。 服务端翻译应使用基于 React context 的钩子,例如
useGT。
设计说明
t() 仅可在浏览器端使用。如果在服务端调用(此时 window 未定义),它会记录一条警告,并回退为源字符串。这是有意为之——服务端翻译应使用现有的基于 React context 的钩子。
API 参考
参阅完整的 t() API 参考,了解参数、返回类型和设置细节。