React中多語(yǔ)言的配置方式
React中多語(yǔ)言的配置
使用React-intl 插件來(lái)實(shí)現(xiàn)全局的多語(yǔ)言控制。
通過(guò)配置JSON key value鍵值對(duì)的形式來(lái)實(shí)現(xiàn)適應(yīng)多語(yǔ)言需求。
第一步
安裝多語(yǔ)言插件: react-intl
npm i react-intl
react-intl
文檔地址:鏈接
第二步
準(zhǔn)備配置工作。
安裝完成以后可以在項(xiàng)目的根目錄中建立一個(gè)locales文件夾來(lái)存放對(duì)應(yīng)的語(yǔ)言包(其實(shí)就是一些key value鍵值對(duì)。)
然后建立兩個(gè)文件夾:分別放置導(dǎo)出的語(yǔ)言配置:我本人的目錄結(jié)構(gòu)如下:
首先是兩個(gè)語(yǔ)言包文件夾: 分別導(dǎo)出index.ts文件夾,后續(xù)如果業(yè)務(wù)有需要可以分別在各自文件夾中建立文件然后在index.ts文件中導(dǎo)入。
以應(yīng)對(duì)后續(xù)業(yè)務(wù)較復(fù)雜語(yǔ)言包較多的情況。
en-US.ts
和 zh-CN.ts
兩個(gè)文件導(dǎo)出了相關(guān)的配置。
這里導(dǎo)出的中文的配置如下:
import message from './zh-CN.message'; import zhCN from 'antd/es/locale/zh_CN'; const zh_CN = { message, antd: zhCN, locale: 'zh-CN', } as { message: any, antd:any, locale: 'zh-CN' | 'en-US' } export default zh_CN
因?yàn)轫?xiàng)目中使用的是React框架,UI組件使用的是antd,antd官方也給出了UI組件的多語(yǔ)言配置所以這里直接從antd中拿到官方導(dǎo)出的組件語(yǔ)言包,供以后組件中使用。
message主要就是自己定義的鍵值對(duì),locale是語(yǔ)言的標(biāo)識(shí)。然后后續(xù)組件就可以引入配置來(lái)配置多語(yǔ)言了。
第三步
引入react-intl 中的組件進(jìn)行配置。
在項(xiàng)目中的APP.tsx文件中進(jìn)行導(dǎo)入。這里盡量在根節(jié)點(diǎn)導(dǎo)入,就像Context的使用方式差不多,在根節(jié)點(diǎn)注入以后,子組件中就可以使用。
在項(xiàng)目中導(dǎo)入Provider
import { IntlProvider } from 'react-intl';
導(dǎo)入antd組件的多語(yǔ)言組件:
import { ConfigProvider } from 'antd';
在根節(jié)點(diǎn)中包裹子組件。盡量在路由組件上方使用。
interface IProps extends RouteComponentProps<any,any>{ children: React.ReactNode } cosnt App:React.FC<IProps> = (props:IProps) => { return( <> <IntlProvider locale={localType.locale} messages={localType.message}> {/* antd中多語(yǔ)言配置 */} <ConfigProvider locale={localType.antd}> <section className="App"> {props.children} </section> </ConfigProvider> </IntlProvider> </> ) }
IntlProvider
是react-intl 導(dǎo)出的Provider,locale是對(duì)應(yīng)的語(yǔ)言標(biāo)識(shí)字符串,message對(duì)應(yīng)的語(yǔ)言key\value 鍵值對(duì)。ConfigProvider
是antd 導(dǎo)出的Proverder, locale 需要導(dǎo)入antd 導(dǎo)出的語(yǔ)言包。
第四步
在系統(tǒng)中維護(hù)一個(gè)字符串來(lái)標(biāo)識(shí)當(dāng)前的語(yǔ)言,可以選擇在Redux中進(jìn)行維護(hù),在App.tsx中可以根據(jù)當(dāng)前語(yǔ)言字符串選擇給IntlProvider和ConfigProvider 賦值不同的配置。
在state.ts中定義初始 state
const store:storeType = { localLanguage: 'en-US' }
然后開(kāi)始寫(xiě)reducer 和 action
//reducer: modal/reducer/index.tsx const localLanguage = (state = store.localLanguage,action:actionType) => { switch(action.type) { case actionType.CHANGE_LANGUAGE: return action.data; default: return state; } } //action: modal/acton/index.tsx export const changeLanguage = (value: 'en-US'| 'zh-CN') => { return { type: storeType.CHANGE_LANGUAGE, data: value } } //導(dǎo)出store modal/index.tsx const store = createStore( reducers, applyMiddleware(thunk) ) export default store;
在根節(jié)點(diǎn)通過(guò)Provider來(lái)注入store
//導(dǎo)入store import { Provider } from 'react-redux'; import store from './modal' //使用Provider ReactDOM.render( <Provider store={store}> <RouterAll/>, </Provider>, document.getElementById('root') );
因?yàn)槲疫@邊想盡可能保持redux中數(shù)據(jù)的純凈,和reducer的純函數(shù)的特性,所以只存入了字符串作為標(biāo)識(shí),所以需要在App.tsx中給多語(yǔ)言組件注入不同的值。
由于App.tsx中是用的react hook的方式來(lái)書(shū)寫(xiě)的,所以使用reducer提供的useSelector 來(lái)讀取store的數(shù)據(jù),根據(jù)標(biāo)識(shí)注入不同的多語(yǔ)言數(shù)據(jù)。
實(shí)現(xiàn)代碼如下:
import {useSelector} from 'react-redux'; import { RouteComponentProps } from 'react-router-dom' import enUS from './locales/en-US' import zhCN from './locales/zh-CN' interface IProps extends RouteComponentProps<any,any>{ children: React.ReactNode } const App:React.FC<IProps> = (props:IProps) => { const localLanguage = useSelector((state:storeType) => state.localLanguage) const [localType,setLocalType] = useState(enUS); useEffect(() => { setLocalType(localLanguage == 'en-US'? enUS: zhCN); },[localLanguage]) return ( <> {/* 多語(yǔ)言配置 */} <IntlProvider locale={localType.locale} messages={localType.message}> {/* antd中多語(yǔ)言配置 */} <ConfigProvider locale={localType.antd}> <section className="App"> {props.children} </section> </ConfigProvider> </IntlProvider> </> ) }
這個(gè)時(shí)候多語(yǔ)言的整體已經(jīng)部署完畢了,接下來(lái)就是在后面的頁(yè)面中進(jìn)行多語(yǔ)言配置。
最后一步在子頁(yè)面中使用多語(yǔ)言:這里分兩步介紹: 分別為hook和Class組件。
hook 組件中 React-intl
導(dǎo)出了對(duì)應(yīng)的鉤子里 來(lái)訪問(wèn)intl實(shí)例。
其中intl是一個(gè)方法可以傳入JSON配置來(lái)達(dá)到想要的效果:這里簡(jiǎn)單的配置了id : 經(jīng)過(guò)intl執(zhí)行以后就會(huì)拿到對(duì)應(yīng)中英文配置的對(duì)應(yīng)key的value
import React, { useState } from 'react'; import { useIntl } from 'react-intl'; import { useSelector, useDispatch } from 'react-redux' import { storeType } from '../../modal/state' import { changeLanguage } from '../../modal/actions' import { Button } from 'antd'; const TestLanguage: React.FC = () => { const { formatMessage: intl } = useIntl(); const state = useSelector((state: storeType) => state); const dispatch = useDispatch(); const changeLanguageEvent = () => { dispatch(changeLanguage(state.localLanguage === 'en-US' ? 'zh-CN' : 'en-US')) } return ( <> <span>{intl({ id: 'login' })}</span> 語(yǔ)言:{state.localLanguage} <hr /> <Button type="primary" onClick={changeLanguageEvent}>{intl({ id: 'testButton' })}</Button> </> ) } export default TestLanguage;
在class 組件中則是需要導(dǎo)入一個(gè)組件來(lái)實(shí)現(xiàn): 通過(guò)組件中傳入對(duì)應(yīng)的屬性,就可以渲染出對(duì)應(yīng)的值。
使用如下:
import React, { Component,PureComponent } from 'react'; import { connect } from 'react-redux' import { changeLanguage } from '../../modal/actions' import { RouteComponentProps } from 'react-router-dom' import { Button } from 'antd'; import { FormattedMessage } from 'react-intl'; import { storeType } from '../../modal/state' interface IProps { localLanguage: 'en-US' | 'zh-CN'; dispatch: Function } class TestLanguageClass extends PureComponent<IProps & RouteComponentProps<any,any>, {}> { constructor(props: IProps & RouteComponentProps<any,any>) { super(props); this.state = { } } private buttonClick = () => { const { localLanguage } = this.props; this.props.dispatch(changeLanguage(localLanguage === 'en-US' ? 'zh-CN' : 'en-US')); } render() { const { localLanguage } = this.props; return ( <> <div> 語(yǔ)言:{localLanguage} <hr /> <Button onClick={this.buttonClick}><FormattedMessage id="testButton" /></Button> </div> </> ) } } export default connect( (state: storeType) => ({ localLanguage: state.localLanguage }), dispatch => ({ dispatch }))(TestLanguageClass);
簡(jiǎn)單的使用場(chǎng)景截圖:
可以看出class組件與hook組件相比,不論在使用 redux 或者是使用多語(yǔ)言,hook都比較簡(jiǎn)介。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
聊聊ant?design?charts?獲取后端接口數(shù)據(jù)展示問(wèn)題
今天在做項(xiàng)目的時(shí)候遇到幾個(gè)讓我很頭疼的問(wèn)題,一個(gè)是通過(guò)后端接口成功訪問(wèn)并又返回?cái)?shù)據(jù),但拿不到數(shù)據(jù)值。其二是直接修改state中的data,console中數(shù)組發(fā)生變化但任然數(shù)據(jù)未顯示,這篇文章主要介紹了ant?design?charts?獲取后端接口數(shù)據(jù)展示,需要的朋友可以參考下2022-05-05React?Router?v6路由懶加載的2種方式小結(jié)
React?Router?v6?的路由懶加載有2種實(shí)現(xiàn)方式,1是使用react-router自帶的?route.lazy,2是使用React自帶的?React.lazy,下面我們就來(lái)看看它們的具體實(shí)現(xiàn)方法吧2024-04-04使用hooks寫(xiě)React組件需要注意的5個(gè)地方
這篇文章主要介紹了使用hooks寫(xiě)React組件需要注意的5個(gè)地方,幫助大家更好的理解和學(xué)習(xí)使用React組件,感興趣的朋友可以了解下2021-04-04React+ResizeObserver實(shí)現(xiàn)自適應(yīng)ECharts圖表
ResizeObserver是JavaScript的一個(gè)API,用于監(jiān)測(cè)元素的大小變化,本文主要為大家介紹了React如何利用ResizeObserver實(shí)現(xiàn)自適應(yīng)ECharts圖表,需要的可以參考下2024-01-01ReactiveCocoa代碼實(shí)踐之-UI組件的RAC信號(hào)操作
這篇文章主要介紹了ReactiveCocoa代碼實(shí)踐之-UI組件的RAC信號(hào)操作 的相關(guān)資料,需要的朋友可以參考下2016-04-04react antd-mobile ActionSheet+tag實(shí)現(xiàn)多選方式
這篇文章主要介紹了react antd-mobile ActionSheet+tag實(shí)現(xiàn)多選方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10React-router中結(jié)合webpack實(shí)現(xiàn)按需加載實(shí)例
本篇文章主要介紹了React-router中結(jié)合webpack實(shí)現(xiàn)按需加載實(shí)例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-05-05