• react(Hooks)实现国际化


    前言

    转到国际项目组之后,做的项目都是多语言的,上次的项目是用vue搭建的,所以使用的是vue-i18n这个插件,具体可以看这:vue3实现国际化

    这次的项目是用react搭建的,也顺手整理一下

    技术栈:Hooks + vite + antd + recoil

    多语言插件使用的是i18next

    安装

    需要同时安装两个包

    $ npm install react-i18next i18next --save
    // or
    $ yarn add react-i18next i18next --save
    
    • 1
    • 2
    • 3

    在src下新建locals文件夹,包含index.js,en.js,zh.js(只做中英文切换)

    // zh.js
    export default {
        login: {
            login: '登录',
            userName: '用户名',
            password: '密码',
            tips: '你好 {{name}}!'
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    // en.js
    export default {
        login: {
            login: 'login',
            userName: 'userName'password: 'password',
            tips: 'hello {{name}}!'
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    // index.js
    import i18n from 'i18next'
    import { initReactI18next } from 'react-i18next'
    import en from './en'
    import zh from './zh'
    
    const resources = {
      en: {
        translation: en
      },
      zh: {
        translation: zh
      }
    }
    
    i18n.use(initReactI18next).init({
      resources,
      lng: localStorage.getItem('lang') || 'en',
      fallbackLng: 'en',
      interpolation: {
        escapeValue: false
      }
    })
    
    export default i18n
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    有个注意的地方就是上面用了缓存,待会会说到为什么要这样做

    最后在main.js引入就好了(这里比vue简单些)

    import '@/locals'
    
    • 1

    至此插件就算配置好了

    使用

    渲染

    对比vue,在react中使用比较简单,只需要用到t方法即可,有两种方式可以使用

    • 引用useTranslation钩子
    import { useTranslation } from 'react-i18next'
    
    const Index = () => {
        const { t } = useTranslation()
        
        return(
        	<div>{t('login.useName')}</div>
            <div>{t('login.tips',{name:'Tony'})}</div>{/* 你好 Tony! */}
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 直接从i18next中引入
    import { t } from 'i18next'
    
    const Index = () => {
        return(
        	<div>{t('login.useName')}</div>
             <div>{t('login.tips',{name:'Tony'})}</div>{/* 你好 Tony! */}
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    关于t()还有很多用法,具体还是去官网看看

    切换语言

    需要用到useTranslation钩子

    import { useTranslation } from 'react-i18next'
    import { Menu, Dropdown, Space } from 'antd'
    
    const Index = () => {
      const { t, i18n } = useTranslation()
      const changeLang = (lang) => {
        i18n.changeLanguage(lang)
        localStorage.setItem('lang', lang)
      }
      const menu = (
        <Menu selectable defaultSelectedKeys={[user.lang]}>
          <Menu.Item key="en" onClick={() => changeLang('en')}>
            English
          </Menu.Item>
          <Menu.Item key="zh" onClick={() => changeLang('zh')}>
            中文
          </Menu.Item>
        </Menu>
      )
      return (
        <div className="header">
          <div className="flex-end">
            <Dropdown overlay={menu} arrow>
              <a onClick={(e) => e.preventDefault()}>
                <Space>
                  {t('language')}
                  <DownOutlined />
                </Space>
              </a>
            </Dropdown>
          </div>
        </div>
      )
    }
    export default Index
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    遇到的问题

    问题其实也是跟之前用vue3+vue-i18n的时候一样,就是刷新后语言又重置了,所以解决办法也是一样,设置缓存就好了

    UI组件语言切换

    antd也是支持多语言的,可以使用ConfigProvider动态切换,在App.jsx里面配置

    // App.jsx
    import React, { Suspense, useState } from 'react'
    import { BrowserRouter} from 'react-router-dom'
    import Routers from './router'
    import './App.css'
    import { ConfigProvider } from 'antd'
    import zhCN from 'antd/es/locale/zh_CN'
    import enUS from 'antd/lib/locale/en_US'
    import { useRecoilState } from 'recoil'
    import { userState } from '@/store/user'
    
    function App() {
      //!! 因为我这个项目是使用recoil全局保存语言的。 你们要根据自己的项目情况修改
      const [user, setUser] = useRecoilState(userState)
      const { lang } = user
      const getLanguage = () => {
        if (lang === 'en') return enUS
        if (lang === 'zh') return zhCN
      }
      return (
        <ConfigProvider locale={getLanguage()}>
          <BrowserRouter>
            <Suspense fallback={<div>Loading...</div>}>
              <Routers />
            </Suspense>
          </BrowserRouter>
        </ConfigProvider>
      )
    }
    
    export default App
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    最后附上我们项目的地址参考 http://egypt.agogopost.com/

    完事

  • 相关阅读:
    20篇NeurIPS论文精选:语言大模型的六大趋势
    【C++】面向对象编程(四)派生类
    IDEA断点调试快捷键
    妹子天天要换新头像?没问题,通过爬虫爬取精美头像
    K8S访问控制------认证(authentication )、授权(authorization )体系
    海上风电应急救援vr模拟安全培训提高企业风险防范能力
    golang 摄像头截图命令版本
    springboot+vue基于java的网上图书商城系统含卖家功能
    双指针--浅试
    【数据库系统概论】第九章关系查询处理何查询优化
  • 原文地址:https://blog.csdn.net/laishaojiang/article/details/125524209