当前位置: 首页 > 工具软件 > i18next > 使用案例 >

react i18next异步加载语言包,调取后端接口

苍恩
2023-12-01

主要还是对于官方文档的理解程度

引官方文档

安装

npm install react-i18next   i18next i18next-http-backend --save

新建i18n文件
–config.ts
–zh.js 本地中文语言 语言json 省略…
–en.js 本地英文语言
– …

config.ts

采用线上获取的接口params

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';

i18n
	.use(Backend)
	.use(initReactI18next)
	.init({
		lng: 'en',
		debug: true,
		interpolation: {
			escapeValue: false
		},
		partialBundledLanguages: true
		// backend: {
		//   loadPath: function (lngs: Array<string>, namespaces: Array<string>) {
		//     console.log(lngs, namespaces,'111');
		//     const type = lngs[0] === 'zh' ? 'zh-CN' : 'en-US';
		//     if (lngs[0] === 'dev') return '';
		//     return `https://as.xiaojukeji.com/ep/as/conf?ns=mdm&name=${type}-test&__caller=di18n-react`;
		//   },
		//   // loadPath: 'https://as.xiaojukeji.com/ep/as/conf?ns=mdm&name=en-US-test&__caller=di18n-react',
		//   parse: function (data: string) {
		//     const obj = eval('(' + data + ')');
		//     return obj.data[0].params;
		//   }
		// }
	});
	
export default i18n;

官方案例
// next-i18next.config.js
const ChainedBackend = require('i18next-chained-backend')
const FSBackend = require('i18next-fs-backend/cjs')
const HttpBackend = require('i18next-http-backend/cjs')

module.exports = {
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'de'],
  },
  backend: {
    backends: [
      FSBackend,
      HttpBackend
    ],
    backendOptions: [{ // make sure public/locales_cache/en and public/locales_cache/de exists
      loadPath: './public/locales_cache/{{lng}}/{{ns}}.json',
      addPath: './public/locales_cache/{{lng}}/{{ns}}.json',
      expirationTime: 7 * 24 * 60 * 60 * 1000 // 7 days
    }, {
      loadPath: '/locales/{{lng}}/{{ns}}.json'
    }]
  },
  use: [ChainedBackend], 使用插件
  ns: ['common', 'footer', 'second-page'], // the namespaces needs to be listed here, to make sure they got preloaded  列出命名空间  默认 translation
  serializeConfig: false, // because of the custom use i18next plugin 插件
  // debug: true,
}

将config文件引入到主入口文件即可

import './i18n/config';

app.ts页面中使用 下面一为示例模块
基础使用,主要核心在于 挂载语言包

import React, { FC, useEffect, useState }  from 'react';
import { Radio } from 'antd';
import i18next from 'i18next';
import Backend from 'i18next-http-backend';
import { useTranslation } from 'react-i18next';
import i18n from 'i18next';
import './style.less';

const Home: FC = () => {
	const { t } = useTranslation();
	const [lang, setLang] = useState('en');

	useEffect(() => {
		console.log('123');
		i18n.addResources('en', 'translation', {
			home: '123'
		});	
		i18n.changeLanguage('en');
	}, []);
	
	const onChange = (e: CommonObjectType) => {
		i18n.changeLanguage(e.target.value);
		console.log(i18n.languages);
		setLang(e.target.value);
	};
	
	return (
		<div className="home-wrapper">
			{t('home')}
			{t('元数据')}
			<Radio.Group onChange={onChange} value={lang}>
				<Radio value="en">英文</Radio>
				<Radio value="zh">中文</Radio>
			</Radio.Group>
		</div>
	);
};

export default Home;

接口调用 图二为配合接口的模块

import React, { FC, useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import useLangHook from '@/hooks/useLangHook';
import './App.less';

const App: FC = () => {
	const { pathname } = useLocation();
	const { getIdent } = useLangHook();
   //这边是监听react 的路由变化,将此方法抽离
	useEffect(() => {
		getIdent(pathname);
		() => {
			return false;
		};
	}, [pathname]);

	return (
		<div></div>
	);
};

export default App;

提取hooks

import Cookie from 'js-cookie';
import i18n from 'i18next';
import { getPageLang } from '@/service/common';

const useLangHook = () => {
	const lang = Cookie.get('lang');
	const routeLang = [
		{
			path: '/infra/module',
			pageCode: 'metadata'
		},
		{
			path: '/infra/engine',
			pageCode: 'engine'
		}
	];
	/**
	 * @param pathname 路由
	 * 根据路由变化监听获取 指定的语言包
	 */
	const getIdent = (pathname) => {
		if (pathname !== '/') {
			getLanguageL(getParams(pathname));
		}
	};

	const getParams = (pathname) => {
		const router= routeLang.find((item) => pathname.startsWith(item.path));
		return { pageCode: router?.pageCode, languageCode: lang };
	};

	/**获取语言的包 */
	const getLanguageL = (params) => {
		i18n.logger.options.defaultNS = [params.pageCode]; //初始化按模块加载,防止英文化切回失效
		if (!i18n.logger.options.ns.includes(params.pageCode)) {
		//调取接口
			getPageLang(params).then((res: CommonObjectType) => {
				i18n.addResources(lang as string, params.pageCode, res.data.params);  //第二个参数动态添加命名模块的空间
				i18n.logger.options.defaultNS = [params.pageCode];  //核心 将默认的defaultNS 命名空间重置当前
				i18n.changeLanguage(lang);
			});
		}
	};
	return {
		getIdent
	};
};

export default useLangHook;

采用本地获取的放式

新建本地的语言json文件

 // 语言标识可以自行配置,不要那么约束  zh zh-ch zh_cn,灵活一点
 "zh-CN": {
    translation:  {
      home:'主页'
   }
  },
  "zh-HK": {
      // json文件不用 示范如何写
      translation: './locales/zh-HK.json'
    },
  "en-US": {
     translation:{
          home:'home'
     }
  },

注意! 注意

除了语言切换时候需要,重新配置下语言
 i18next.changeLanguage(Cookies.get('lang'));

一定要初始化的时候也要设置下默认的语言,否则不生效

示例

react  hooks中示例,不加这个默认不加载默认的语言配置
import React, { useEffect } from 'react';
  useEffect(() => {
    //初始化加载一次语言包配置,不然后面获取不到
    i18next.changeLanguage(Cookies.get('lang'));
  }, []);

简单示例,如有不足,请多指教

 类似资料: