使用Redux在React中使用多语言

时间:2019-07-02 10:31:26

标签: reactjs redux reducers

我是React的新手(但是我已经使用ReactNative制作了一个简单的应用程序)。我制作了一个简单的Web应用程序,其中只有很少的组件可以进行用户登录。问题在于它必须支持多语言,而我无法完全理解如何使用redux来将系统语言从子组件“菜单”更改为应用程序中即将或将要加载的所有组件。

以下是主要组成部分:

index.js

import React from 'react';
import ReactDOM from 'react-dom';

import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(
    <App />,
    document.getElementById('root')
);

App.js

import React, {Component} from 'react';
import { BrowserRouter as Router, Route, Link, Redirect } from "react-router-dom";

import Globals from './globals/globals.js';

import './assets/css/main.css';

import Menu from './components/Menu.js';
import Footer from './components/Footer.js';
import Loading from './components/Loading.js';

import Login from './pages/Login.js';
import Home from './pages/Home.js';

export default class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            language: "en",
            accessToken: "",
            isLogged: undefined,
        }
    }

    componentDidMount(props) {
        // Get access token if stored
        let accessToken = localStorage.getItem('accessToken');

        if ( accessToken !== undefined && accessToken !== null && accessToken !== '' ) {
            // Try to contact the server to see if it's still viable

        } else {
            // Go to the login page because you're certainly not logged
            localStorage.setItem( 'accessToken', "" );
            this.setState({
                accessToken: "",
                isLogged: false,
            });
        }
    }

    render() {
        let redirect;
        if ( this.state.isLogged === false ) {
            redirect = <Redirect to={{ pathname: '/login' }} />;
        }

        let pages;
        if ( this.state.isLogged === undefined ) {
            pages = <Loading/>;
        } else {
            pages = <div>
                <Route exact path="/" component={Home} />
                <Route path="/login" component={Login} />
            </div>;
        }

        return(
                <Router>
                    <div className="page-wrapper">
                        <Menu />
                        <div className="site-content">
                            {pages}
                            {redirect}
                        </div>
                        <Footer />
                    </div>
                </Router>
        );
    }

}

Menu.js

import React, { Component } from 'react';
import logo from './../assets/img/logo.png';

export default class Menu extends Component {

    constructor(props) {
        super(props);

        this.state = {
            language: "en",
            menuState: 0,
        }
    }

    toggleMenu() {
        this.setState({
            menuState: 1 - this.state.menuState
        });
    }

    changeLanguage(language) {
        alert('change language');
    }

    render() {
        return(
            <header>
                <div className="menu-bar">
                    <div className="top-bar">
                        <div className="icon open" onClick={this.toggleMenu.bind( this )}></div>
                        <div className="logo-wrapper">
                            <img src={logo} alt="logo" />
                        </div>
                        <div className="language-selection-wrapper"></div>
                    </div>
                    <div className={this.state.menuState === 1 ? "menu-body opened" : "menu-body closed"}>
                        <div className="menu-sidebar">
                            <div className="sidebar-content">
                                <div className="sidebar-top-bar">
                                    <div className="icon close" onClick={this.toggleMenu.bind( this, 1 )}></div>
                                    <div className="logo-wrapper">
                                        <img src={logo} alt="logo" />
                                    </div>
                                </div>
                                <div className="language-selection-wrapper">
                                    <div className={this.state.language === 'it' ? "language current" : "language"} onClick={this.changeLanguage.bind(this, 'it')}>IT</div>
                                    <div className={this.state.language === 'en' ? "language current" : "language"} onClick={this.changeLanguage.bind(this, 'en')}>EN</div>
                                    <div className={this.state.language === 'de' ? "language current" : "language"} onClick={this.changeLanguage.bind(this, 'de')}>DE</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </header>
        );
    }

}

最后还有Login.js

import React, { Component } from 'react';

import Globals from './../globals/globals.js';

import Loading from './../components/Loading.js';

import 'font-awesome/css/font-awesome.min.css';

export default class Login extends Component {

    constructor(props) {
        super(props);

        this.state = {
            language: "en",
            loading: false
        }
    }

    componentDidMount(){
        document.title = "Login"
    }

    doLogin() {
        alert('Fai il login');
        this.setState({
            loading: true
        });
    }

    render() {
        let loading;
        if ( this.state.loading === true ) {
            loading = <Loading/>;
        }

        return(
            <div className="login-box">
                <div className="welcome-message">
                    {Globals.messages.welcome[this.state.language]}
                </div>
                <div className="input-wrapper">
                    <input type="text" name="username" placeholder={Globals.placeholders.email[this.state.language]} />
                </div>
                <div className="input-wrapper">
                    <input type="password" name="password" placeholder={Globals.placeholders.password[this.state.language]} />
                </div>
                <div className="input-wrapper">
                    <button type="button" onClick={this.doLogin.bind(this)}><i className="fa fa-sign-in"></i><span>{Globals.placeholders.login[this.state.language]}</span></button>
                </div>
                {loading}
            </div>
        );
    }

}

我还提供了带有翻译的globals.js文件

const Globals = {
    baseUrl: "https://www.mywebsite.it/webservices/1.0/",

    messages: {
        welcome: {
            it: "Benvenuto!",
            en: "Welcome!",
            de: "Willkommen!",
        },
    },

    placeholders: {
        email: {
            it: "Email",
            en: "Email",
            de: "Email",
        },
        password: {
            it: "Password",
            en: "Password",
            de: "Password",
        },
        login: {
            it: "Login",
            en: "Login",
            de: "Login",
        },
    },
}

export default Globals;

1 个答案:

答案 0 :(得分:2)

您不需要Redux进行国际化。 看看:

https://github.com/formatjs/react-intl

这是国际化的行业默认值。