回文章列表

在React專案中引入React-i18next心得

最近公司有React專案有多語系切換的需求,在整合的過程中,有一些心得感想跟大家分享。

在這個需求出來之後,我搜尋了React的i18n相關套件,發現了 React-i18next,我整合的過程大概如下

1.先準備好你預先翻譯好的語系檔並且放進專案的目錄中,我是在 src 中新建 asset 資料夾以便放置一些靜態的檔案(不一定要照我的,可以放到自己喜歡的地方)

// src/asset/i18n/zh-TW.json
{
  "quickAdd": {
    "title": "快速新增",
    "listTitle": {
      "customer": "客戶",
      "company": "公司",
      "work": "工作",
      "meeting": "會議",
      "event": "事件/活動",
      "business": "商機",
      "consumption": "消費",
      "coupon": "點券",
      "message": "行銷簡訊",
      "mail": "行銷郵件",
      "contact": "聯繫腳本",
      "note": "記事本",
      "announcement": "佈告欄",
      "tag": "標籤"
    }
  },
}

語系檔範例


reacti18next1.png

檔案結構範例


2.新建 i18n.js,引入語系檔與設定參數

// src/i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import en from './assets/i18n/en.json';
import jp from './assets/i18n/ja-JP.json';
import tw from './assets/i18n/zh-TW.json';

const resources = {
  en: {
    translation: en,
  },
  'ja-JP': {
    translation: jp,
  },
  'zh-TW': {
    translation: tw,
  },
};

i18n.use(initReactI18next).init({
  resources,
  lng: 'zh-TW',             //預設語言
  fallbackLng: 'zh-TW',     //如果當前切換的語言沒有對應的翻譯則使用這個語言,
  interpolation: {
    escapeValue: false,
  },
});

export default i18n;

如果語系檔中有巢狀的結構,則 escapeValue 要設為 false,這樣就可以透過物件的方式來取得巢狀內的翻譯


3.在入口檔案 import 剛剛的 i18n

// src/index.js
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Root from './Root';
import registerServiceWorker from './registerServiceWorker';

import './i18n';

const root = document.getElementById('root') as HTMLElement;

ReactDOM.render(<Root />, root);

registerServiceWorker();

4.接下來就可以透過 Translation(hoc) 或是 useTranslation (hook) 來達成多語系切換的功能

// path/to/yourComponent.js

/* Class Components */
import { Translation } from 'react-i18next';

class Hello extends React.Component{
  render() {
    return (
      <Translation>
        {t => (
          <World>{t('quickAdd.title')}<World>
        )}
      </Translation>
    );
  }
}

Class Components 可以使用 Translation 完成我們的目的


// path/to/yourComponent.js

/* Functional Components */
import { useTranslation } from 'react-i18next';

// es5
function Hello() {
  const { t } = useTranslation();
  return (
    <World>{t('quickAdd.title')}<World>
  );
}

// es6
const Hello = ()=>{
  const { t } = useTranslation();
  return (
    <World>{t('quickAdd.title')}<World>
  );
}

如果是 functional component 則可以使用 useTranslation


5.接著透過解構拿出 i18n ,使用 i18n.changeLanguage 函數來切換當前語系檔,這邊我有使用 useEffect 使我 state 中的 lang 一改變就直接觸發修改語系

// path/to/yourComponent.js

/* 切換語系 */
  const { i18n } = useTranslation();

  //React hook
  const [lang, setLang] = useState<Lang>(null);
  useEffect(() => {
    if (lang !== null) i18n.changeLanguage(lang.value);
  }, [lang]);

  setLang('zh-TW');
  setLang('en');
  setLang('ja-JP');

心得有點倉促 我有機會會再來修改這一篇文章

參考資料: react-i18next:https://www.i18next.com/

發表於 Feb 18, 2019

You cannot improve your past, but you can improve your future.Ryan Chu on Github