受withApollo的启示,仔细研究了一下context的API,在开发中还没用过context,但是想antd中的form这种跨组件传递数据,那i18n正适合啊
先来三个基本组件,到时候准备替换的就是title和desc
import React, { useState } from 'react' const Title = () => { return ( <div>title</div> ) } const Descrption = () => { return ( <div>desc</div> ) } const Container = () => { return ( <div> <Title /> <Descrption /> </div> ) } export default Container 复制代码
准备了en和cn的两个版本的语言配置文件:
// en.js export default { locale: 'en', messages: { title: 'title', desc: 'this is description' } } // zh-CN.js export default { locale: 'zh-CN', messages: { title: '中文', desc: '这是一段描述' } } 复制代码
加载语言配置,
// load_language.js import en from './en' import zhCN from './zh-CN' const list = { [en.locale]: en.messages, [zhCN.locale]: zhCN.messages } 复制代码
写到这,我想起来webpack的ignore的plugin,加载多语言配置,肯定会将所有的语言全都load,假如你只需要cn,那么其他的语言包对你来说都是没有用的。经常见的就是moment这个,你会使用ignorePlugin忽略它,然后再手动引入
1、 准备conext
// context.js import React from 'react' const LanguageContext = React.createContext('zh-CN') export default LanguageContext 复制代码
2、向load_language增加消费:
const t = (title) => { return ( <LanguageContext.Consumer> {language => ( list[language][title] )} </LanguageContext.Consumer> ) } 复制代码
3、然后我就可以直接改造我的title和desc了:
const Title = () => { return ( <div>{t('title')}</div> ) } const Descrption = () => { return ( <div>{t('desc')}</div> ) } 复制代码
4、Container中增加切换语言的按钮:
const [language, setLanguage] = useState('zh-CN') const changeLanguage = () => { setLanguage(language === 'zh-CN' ? 'en' : 'zh-CN') } return ( <LanguageContext.Provider value={language}> <button onClick={changeLanguage}>切换语言:当前是{language}</button> <Title /> <Descrption /> <Descrption22 /> </LanguageContext.Provider> ) } 复制代码
ok,可以了
另外,t还可以使用hoc的形式注入
export const withLanguage = (Component) => (props) => { return ( <LanguageContext.Consumer> { language => ( <Component {...props} t={(title) => list[language][title] } /> ) } </LanguageContext.Consumer> ) } 复制代码
在组件中使用:
const Descrption2 = ({ t }) => { return ( <div>hoc: {t('desc')}</div> ) } const Descrption22 = withLanguage(Descrption2) 复制代码
走到这,一个简单的i18n就完成了。
PS: 如果中文网站要做国际化的话,可能最快的方式还是开发一套英文网站,再它的基础上做国际化。中文转英文,长度是由短变长,排版上改的会让人崩溃。