React學習筆記02 實作多語言切換

2023/10/17 學習筆記 React React

React實作多語言切換

工作上遇到的需求,要利用React實作多語言切換

Install react-i18next i18next

Import react-i18next i18next.\

npm install react-i18next i18next

範例程式 LanguageSelector.jsx

import React, { useState } from 'react';
import styles from './LanguageSelector.module.css'

import { useTranslation } from "react-i18next";

import IconCN from '../assets/cn.svg'
import IconGB from '../assets/gb.svg'

const LanguageSelector = () => {
  // Initialize the i18n object for translation
  const { i18n } = useTranslation();
  // Initialize state for the selected language
  const [selectedLanguage, setSelectedLanguage] = useState('zh-cn'); // Default to Chinese

  // Handle language selection
  const handleLanguageChange = (languageCode) => {
    // Update the selected language in state
    setSelectedLanguage(languageCode);
    // Change the language using i18n
    i18n.changeLanguage(languageCode.replace("-", ""));

  };

  return (
    <div className={styles.languageSelector}>
      {/* Create a button for selecting Chinese language */}
      <div
        className={`${styles.lang_button} ${selectedLanguage === 'zh-cn' ? 'selected' : ''}`}
        onClick={() => handleLanguageChange('zh-cn')}
      >
        <img className={styles.img} src={IconCN} alt="IconCN" />
      </div>
      {/* Create a button for selecting English language */}
      <div
        className={`${styles.lang_button} ${selectedLanguage === 'en' ? 'selected' : ''}`}
        onClick={() => handleLanguageChange('en')}
      >
        <img className={styles.img} src={IconGB} alt="IconGB" />
      </div>
    </div>
  );
};

export default LanguageSelector;

範例程式 LanguageSelector.module.css

.languageSelector {
    display: flex;
}

.img {
    width: 40px;
    height: 40px;
    border-radius: 50%;
}

.lang_button {
    margin-left: 3px;
    margin-right: 3px;
    background-color: #ffffff00;
}

範例程式 Header.jsx

import { React, useState } from 'react';
import Logo from '../assets/logo.svg'
import { AiOutlineMenu, AiOutlineClose, } from 'react-icons/ai';
import styles from './Header.module.css'
import LanguageSelector from './LanguageSelector'; // import LanguageSelector
import { useTranslation } from "react-i18next"; // import react-i18next

const Header = () => {
  // create Translation t
  const { t } = useTranslation();
  // Create a state variable 'nav' and a function 'setNav' to toggle the navigation menu
  const [nav, setNav] = useState(false);
  return (
    <>
      <header>
        <img src={Logo} alt='Logo' />
        <nav>
          <ul className={nav ? [styles.menu, styles.active].join(' ') : [styles.menu]} >
            <li>
              <a href='/#'>{t("home")}</a>
            </li>
            <li>
              <a href='/#'>{t("about_us")}</a>
            </li>
            <li>
              < a href='/#'>{t("contact_us")}</a>
            </li>
            <li>
              <LanguageSelector />
            </li>
          </ul>
        </nav>
        {/* Create a button to toggle the mobile menu */}
        <div onClick={() => setNav(!nav)} className={styles.mobile_btn}>
          {/* Display the close or menu icon based on the 'nav' state */}
          {nav ? <AiOutlineClose size={30} color='white' /> : <AiOutlineMenu size={30} color='white' />}
        </div>
      </header>
    </>
  );
}

export default Header;

範例程式 main.jsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import './main.css';

import { I18nextProvider } from "react-i18next";
import locales_en from "./locales/en.json";
import locales_cn from "./locales/cn.json";
import i18next from "i18next";

// Initialize i18next for internationalization
i18next.init({
  interpolation: { escapeValue: false },
  lng: "zhcn", // Set the default language to Chinese
  resources: {
    zhcn: {
      translation: locales_cn // Define translations for Chinese
    },
    en: {
      translation: locales_en // Define translations for English
    }
  }
});

// Render the React app with internationalization support
ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <I18nextProvider i18n={i18next}>
      <App />
    </I18nextProvider>
  </React.StrictMode>
);

範例程式 en.json

{
    "home":"Home",
    "about_us":"About us",
    "contact_us":"Contact us"
}

範例程式 cn.json

{
    "home":"主页",
    "about_us":"关于我",
    "contact_us":"联系我"
}

成果

網頁版

手機版

結語

本次實作多語言,下次會介紹Route






Search

    Post Directory