多语言切换核心是统一管理 locale 和 messages 并自动触发组件重渲染。使用 React Context + useReducer 创建 I18nContext,提供 t() 函数支持嵌套键、默认回退与插值,配合 useMemo/useCallback 优化性能,并同步更新 title、aria-label 等隐性文本。

用全局状态管理多语言切换,核心是把当前语言标识(如 zh、en)和翻译映射表统一维护,并让所有依赖文案的组件自动响应变化。关键不在“存语言”,而在“通知重渲染”和“按需取值”。
用 React Context + useReducer 管理语言状态
避免分散的 useState 或 props 逐层传递。创建一个 I18nContext,包裹整个应用:
- state 包含
locale(当前语言码)和messages(当前语言的键值对对象) - dispatch 一个
setLocaleaction,触发更新:根据新 locale 从预加载的资源中取出对应 messages,并更新 context - 自定义 hook
useI18n()封装 useContext,返回{ t, locale, setLocale }
文案函数 t() 要支持嵌套键与默认回退
t('header.title') 比 t('title') 更易维护,尤其在大型项目中。实现时注意:
- 用点号分割路径,递归查找嵌套对象(如
messages.header.title) - 若键不存在,返回 key 本身(如
t('missing.key')→ 显示missing.key),方便定位漏翻译项 - 支持简单插值:
t('welcome', { name: 'Alice' })→'欢迎,Alice!'
组件内响应式更新靠 useMemo + useCallback 避免重复计算
每次 locale 变,所有调用 t() 的组件都会重新执行函数体——但不意味着必须重渲染。优化点:
- 在
useI18n()中,用useMemo缓存当前messages对象,确保引用稳定 - 将
t函数用useCallback包裹,防止父组件重渲染时子组件因函数引用变化而误更新 - 文案密集型组件(如设置页)可加
React.memo,依赖t的返回值做浅比较
语言资源预加载与动态加载策略
中文、英文等主力语言建议随包加载;小语种可按需 import:
- 初始化时加载默认语言(如
import zh from './locales/zh.json') - 切换到
ja时,触发import('./locales/ja.json').then(setMessages),期间显示 loading 文案或保留旧文案 - 服务端渲染(SSR)场景下,需在首屏前同步注入对应 locale 数据,避免闪动
不复杂但容易忽略:语言切换后,除了 UI 文案,还要同步更新 document.title、aria-label、placeholder 等隐性文本,这些都应走同一套 t() 流程。

















