react 使用i18next,react-i18next 实现多语言切换

1,898 阅读2分钟

react 使用i18next,react-i18next 实现多语言切换

一、安装

npm i react-i18next i18next i18next-browser-languagedetector -S

二、配置

在src下面创建以下目录格式文件

i18n
|-- index.ts 
|-- locales
    |-- en.json
    |-- zh.json

en.json

{
  "语言": {
    "中文": "Chinese",
    "英文": "English"
  },
  "用户操作": {
    "个人中心": "Personal center",
    "个人设置": "Personal Settings",
    "退出登录": "Log out"
  }
}

zh.json

{
  "语言": {
    "中文": "中文",
    "英文": "英文"
  },
  "用户操作": {
    "个人中心": "个人中心",
    "个人设置": "个人设置",
    "退出登录": "退出登录"
  }
}

index.ts

import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
// i18next-browser-languagedetector插件 这是一个 i18next 语言检测插件,用于检测浏览器中的用户语言,
// 详情请访问:https://github.com/i18next/i18next-browser-languageDetector
// 可以通过localStorage.getItem('i18nextLng')取出当前语言环境
import LanguageDetector from 'i18next-browser-languagedetector'

// 引入需要实现国际化的简体、英文两种数据的json文件
import zhTranslation from './locales/zh.json'
import enTranslation from './locales/en.json'

i18n
  .use(LanguageDetector) // 嗅探当前浏览器语言 zh-CN
  .use(initReactI18next) // 将 i18n 向下传递给 react-i18next
  // 初始化 i18next
  // 配置参数的文档: https://www.i18next.com/overview/configuration-options
  .init({
    resources: {
      en: { translation: enTranslation },
      zh_CN: { translation: zhTranslation },
    },
    fallbackLng: 'zh_CN', // 默认当前环境的语言
    // 需要链式调用messages.welcome
    // keySeparator: false, // we do not use keys in form messages.welcome
    debug: false,
    interpolation: { escapeValue: false },
  })

export default i18n

三、使用

1、在入口index处导入i18n配置文件

index.ts

import React from 'react'
import ReactDOM from 'react-dom/client'
import '@/i18n'
import App from '@/App'

const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

2、在hook组件中使用

1、i18n数据的获取

核心代码

import { useTranslation } from 'react-i18next'

const { t } = useTranslation()

<div>t('用户操作.个人中心')</div>
import React, { FC } from 'react'
import { Image, Dropdown, Menu } from 'antd'
import type { MenuProps } from 'antd'
import {
  SettingOutlined,
  UserOutlined,
  LogoutOutlined,
} from '@ant-design/icons'

import { useTranslation } from 'react-i18next'

interface childProp {
  userAvatar: string // 登录成功用户头像
  userName: string // 登录成功用户名称
}

/**
 * 系统头部用户组件
 */
const User: FC<childProp> = props => {
    
  const { t } = useTranslation() // 根据当前语言环境获取i18n读取数据

  // 用户操作事件
  const handelUserOpreation: MenuProps['onClick'] = ({ key }) => {
    console.log(`用户点击了${key}`)
  }

  const menu = (
    <Menu
      onClick={handelUserOpreation}
      items={[
        {
          label: t('用户操作.个人中心'),
          key: '/user/info',
          icon: <UserOutlined />,
        },
        {
          label: t('用户操作.个人设置'),
          key: '/user/setting',
          icon: <SettingOutlined />,
        },
        {
          type: 'divider',
        },
        {
          label: t('用户操作.退出登录'),
          icon: <LogoutOutlined />,
          key: '/user/logout',
        },
      ]}
    />
  )
  return (
    <Dropdown overlay={menu}>
      <div className="icon">
        <Image preview={false} width={30} src={props.userAvatar} />
        <span className="user-name">{props.userName}</span>
      </div>
    </Dropdown>
  )
}

export default User

2、切换语言环境

核心代码

import { useTranslation } from 'react-i18next'

const { t, i18n } = useTranslation()

i18n.changeLanguage(当前改变的语言)
import React, { FC, useState } from 'react'
import { Dropdown, Menu } from 'antd'
import type { MenuProps } from 'antd'
import { DribbbleOutlined } from '@ant-design/icons'
import { useTranslation } from 'react-i18next'

/**
 * 语言选择组件
 */
const Language: FC<{}> = () => {
  const { t, i18n } = useTranslation()
  const [selectedKeys, setSelectedKeys] = useState([i18n.language])
  // 切换语言事件
  const handleChangeLanguage: MenuProps['onClick'] = ({ key }) => {
    setSelectedKeys([key])
    i18n.changeLanguage(key)
  }

  const menu = (
    <Menu
      onClick={handleChangeLanguage}
      style={{ width: 100 }}
      selectedKeys={selectedKeys}
      items={[
        {
          label: t('语言.中文'),
          key: 'zh_CN',
        },
        {
          label: t('语言.英文'),
          key: 'en',
        },
      ]}
    />
  )

  return (
    <Dropdown overlay={menu}>
      <div className="icon">
        <DribbbleOutlined />
      </div>
    </Dropdown>
  )
}

export default Language