React中多语言的配置方式

 更新时间:2023年06月07日 09:05:56   作者:shuuy  
这篇文章主要介绍了React中多语言的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

React中多语言的配置

使用React-intl 插件来实现全局的多语言控制。

通过配置JSON key value键值对的形式来实现适应多语言需求。

第一步

安装多语言插件: react-intl

npm i react-intl

react-intl 文档地址:链接

第二步

准备配置工作。

安装完成以后可以在项目的根目录中建立一个locales文件夹来存放对应的语言包(其实就是一些key value键值对。)

然后建立两个文件夹:分别放置导出的语言配置:我本人的目录结构如下:

首先是两个语言包文件夹: 分别导出index.ts文件夹,后续如果业务有需要可以分别在各自文件夹中建立文件然后在index.ts文件中导入。

以应对后续业务较复杂语言包较多的情况。

en-US.tszh-CN.ts 两个文件导出了相关的配置。

这里导出的中文的配置如下:

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

因为项目中使用的是React框架,UI组件使用的是antd,antd官方也给出了UI组件的多语言配置所以这里直接从antd中拿到官方导出的组件语言包,供以后组件中使用。

message主要就是自己定义的键值对,locale是语言的标识。然后后续组件就可以引入配置来配置多语言了。

第三步

引入react-intl 中的组件进行配置。

在项目中的APP.tsx文件中进行导入。这里尽量在根节点导入,就像Context的使用方式差不多,在根节点注入以后,子组件中就可以使用。

在项目中导入Provider

import { IntlProvider } from 'react-intl';

导入antd组件的多语言组件:

import { ConfigProvider } from 'antd';

在根节点中包裹子组件。尽量在路由组件上方使用。

    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中多语言配置 */}
                    <ConfigProvider locale={localType.antd}>
                        <section className="App">
                            {props.children}
                        </section>
                    </ConfigProvider>
                </IntlProvider>
            </>
        )
    }
  • IntlProvider 是react-intl 导出的Provider,locale是对应的语言标识字符串,message对应的语言key\value 键值对。
  • ConfigProvider 是antd 导出的Proverder, locale 需要导入antd 导出的语言包。

第四步

在系统中维护一个字符串来标识当前的语言,可以选择在Redux中进行维护,在App.tsx中可以根据当前语言字符串选择给IntlProvider和ConfigProvider 赋值不同的配置。

在state.ts中定义初始 state

const store:storeType =  {
    localLanguage: 'en-US'
}

然后开始写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
    }
}
//导出store modal/index.tsx
const store = createStore(
    reducers,
    applyMiddleware(thunk)
)
export default store;

在根节点通过Provider来注入store

//导入store
import { Provider } from 'react-redux';
import store from './modal'
//使用Provider
ReactDOM.render(
  <Provider store={store}>
    <RouterAll/>,
  </Provider>,
  document.getElementById('root')
);

因为我这边想尽可能保持redux中数据的纯净,和reducer的纯函数的特性,所以只存入了字符串作为标识,所以需要在App.tsx中给多语言组件注入不同的值。

由于App.tsx中是用的react hook的方式来书写的,所以使用reducer提供的useSelector 来读取store的数据,根据标识注入不同的多语言数据。

实现代码如下:

  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 (
    <>
        {/* 多语言配置 */}
        <IntlProvider locale={localType.locale} messages={localType.message}>
          {/* antd中多语言配置 */}
          <ConfigProvider locale={localType.antd}>
            <section className="App">
              {props.children}
            </section>
          </ConfigProvider>
        </IntlProvider>
    </>
  )
}

这个时候多语言的整体已经部署完毕了,接下来就是在后面的页面中进行多语言配置。

最后一步在子页面中使用多语言:这里分两步介绍: 分别为hook和Class组件。

hook 组件中 React-intl 导出了对应的钩子里 来访问intl实例。

其中intl是一个方法可以传入JSON配置来达到想要的效果:这里简单的配置了id : 经过intl执行以后就会拿到对应中英文配置的对应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>
            语言:{state.localLanguage}
            <hr />
            <Button type="primary" onClick={changeLanguageEvent}>{intl({ id: 'testButton' })}</Button>
        </>
    )
}
export default TestLanguage;

在class 组件中则是需要导入一个组件来实现: 通过组件中传入对应的属性,就可以渲染出对应的值。

使用如下:

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>
                    语言:{localLanguage}
                    <hr />
                    <Button onClick={this.buttonClick}><FormattedMessage
                        id="testButton"
                    /></Button>
                </div>
            </>
        )
    }
}
export default connect(
    (state: storeType) => ({ localLanguage: state.localLanguage }),
    dispatch => ({ dispatch }))(TestLanguageClass);

简单的使用场景截图:

可以看出class组件与hook组件相比,不论在使用 redux 或者是使用多语言,hook都比较简介。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 浅谈React前后端同构防止重复渲染

    浅谈React前后端同构防止重复渲染

    这篇文章主要介绍了浅谈React前后端同构防止重复渲染,首先解释React前后端同构、React首屏渲染的概念。然后通过这2个概念解决服务端渲染完成后浏览器端重复渲染的问题。有兴趣的可以了解一下
    2018-01-01
  • React版本18.xx降低为17.xx的方法实现

    React版本18.xx降低为17.xx的方法实现

    由于现在react默认创建是18.xx版本,但是我们现在大多使用的还是17.xx或者更低的版本,于是要对react版本进行降级,本文主要介绍了React版本18.xx降低为17.xx的方法实现,感兴趣的可以了解一下
    2023-11-11
  • React父组件如何调用子组件的方法推荐

    React父组件如何调用子组件的方法推荐

    在React中,我们经常在子组件中调用父组件的方法,一般用props回调即可,这篇文章主要介绍了React父组件如何调用子组件的方法推荐,需要的朋友可以参考下
    2023-11-11
  • React.js绑定this的5种方法(小结)

    React.js绑定this的5种方法(小结)

    this在javascript中已经相当灵活,这篇文章主要介绍了React.js绑定this的5种方法(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 关于React16.0的componentDidCatch方法解读

    关于React16.0的componentDidCatch方法解读

    这篇文章主要介绍了关于React16.0的componentDidCatch方法解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • React冒泡和阻止冒泡的应用详解

    React冒泡和阻止冒泡的应用详解

    这篇文章主要介绍了React冒泡和阻止冒泡的应用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • 在React项目中实现一个简单的锚点目录定位

    在React项目中实现一个简单的锚点目录定位

    锚点目录定位功能在长页面和文档类网站中非常常见,它可以让用户快速定位到页面中的某个章节,本文讲给大家介绍一下React项目中如何实现一个简单的锚点目录定位,文中有详细的实现代码,需要的朋友可以参考下
    2023-09-09
  • React各种状态管理器的解读及使用方法

    React各种状态管理器的解读及使用方法

    这篇文章主要介绍了对于React各种状态管理器的解读,文中给大家提到了状态管理器是如何使用的,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • react-router4 配合webpack require.ensure 实现异步加载的示例

    react-router4 配合webpack require.ensure 实现异步加载的示例

    本篇文章主要介绍了react-router4 配合webpack require.ensure 实现异步加载的示例,非常具有实用价值,需要的朋友可以参考下
    2018-01-01
  • 使用React.forwardRef传递泛型参数

    使用React.forwardRef传递泛型参数

    这篇文章主要介绍了使用React.forwardRef传递泛型参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05

最新评论