React / Redux ve Çok Dilli (Uluslararasılaştırma) Uygulamalar - Mimari


119

Birden çok dilde ve yerel ayarda bulunması gereken bir uygulama geliştiriyorum.

Sorum tamamen teknik değil, daha çok mimari ve insanların bu sorunu çözmek için üretimde kullandıkları kalıplarla ilgili. Bunun için hiçbir "yemek kitabı" bulamadım, bu yüzden en sevdiğim soru / cevap web sitesine dönüyorum :)

İşte gereksinimlerim (bunlar gerçekten "standarttır"):

  • Kullanıcı dili seçebilir (önemsiz)
  • Dili değiştirdikten sonra, arayüz otomatik olarak yeni seçilen dile çevrilmelidir
  • Şu anda sayıları, tarihleri ​​vb. Biçimlendirme konusunda çok endişelenmiyorum, yalnızca dizeleri çevirmek için basit bir çözüm istiyorum

İşte düşünebileceğim olası çözümler:

Her bileşen ayrı ayrı çeviri ile ilgilenir

Bu, her bileşenin örneğin bir dizi en.json, fr.json vb. Dosyalarının yanı sıra çevrilmiş dizelerle birlikte olduğu anlamına gelir. Ve seçilen dile bağlı olarak değerlerin okunmasına yardımcı olacak bir yardımcı işlev.

  • Pro: React felsefesine daha saygılı, her bileşen "bağımsızdır"
  • Eksileri: bir dosyadaki tüm çevirileri merkezileştiremezsiniz (örneğin başka birinin yeni bir dil eklemesini sağlamak için)
  • Eksileri: Mevcut dili, her kanlı bileşende ve çocuklarında hala bir destek olarak geçirmeniz gerekiyor

Her bileşen, çevirileri sahne aracılığıyla alır

Bu yüzden mevcut dilin farkında değiller, sadece mevcut dille eşleşen bir dizi dizgeyi sahne olarak alıyorlar.

  • Pro: Bu dizeler "üstten" geldiğinden, bir yerde merkezileştirilebilirler
  • Eksileri: Her bileşen artık çeviri sistemine bağlıdır, yalnızca birini yeniden kullanamazsınız, her seferinde doğru dizeleri belirlemeniz gerekir

Destekleri biraz atlarsınız ve muhtemelen mevcut dili geçmek için bağlam şeyini kullanırsınız

  • Pro: Çoğunlukla şeffaftır, mevcut dili ve / veya çevirileri her zaman sahne üzerinden geçirmek zorunda değildir
  • Eksileri: Kullanması hantal görünüyor

Başka bir fikriniz varsa lütfen söyleyin!

Bunu nasıl yapıyorsun?


2
Nesne olarak aktarılan çeviri dizelerine sahip bir anahtar nesnesi fikrini tercih ederim, her dizgeyi bir destek olarak ayrı ayrı geçirmek zorunda değilsiniz. Bunu en üst düzeyde değiştirmek, yeniden oluşturmayı tetiklemelidir. Bağlam kullanmanın bunun için iyi bir fikir olduğunu düşünmüyorum ve çeviri dosyasına erişimi olan her bileşen onları daha az "aptal" ve aslında daha kolay taşınabilir hale getiriyor (ve dil değişikliğinde uygulamayı yeniden oluşturmayı zorlaştırıyor).
Dominic

1
Aslında facebook.github.io/react/docs/context.html'ye göre , geçerli dili paylaşmak için bağlam kullanmak meşru kullanım durumlarından biridir. Şu anda denediğim yaklaşım, bu bileşenin dizelerini çıkarmanın mantığıyla başa çıkmak için bu artı bir Yüksek
Dereceli

1
Belki de bir göz alabilir Anında . Bu sorunu tamamen farklı bir şekilde ön uçta ala Optimizely (diğer bir deyişle yükleme sırasında DOM'yi değiştirerek) çözerek ele alırlar.
Marcel Panse

1
Hiç de fena değil! Gerçekten de tamamen farklı bir canavar (bu, sizi web siteniz büyüdüğünde ödemeniz gerekebilecek bir hizmete bağlar), ancak bu fikri beğendim ve muhtemelen hızlı bir şekilde yayınlamanız gereken küçük bir web sitesi için buna değer!
Antoine Jaussoin

4
Ayrıca, sanki onlarla hiçbir
ilginiz yokmuş

Yanıtlar:


110

Epeyce çözüm denedikten sonra, sanırım iyi çalışan ve React 0.14 için deyimsel bir çözüm olması gereken bir çözüm buldum (yani mixin kullanmıyor, ancak Higher Order Bileşenleri kullanıyor) ( düzenleme : React 15 ile de gayet iyi tabi ki! ).

İşte çözüm, alttan başlayarak (tek tek bileşenler):

Bileşen

Bileşeninizin ihtiyaç duyacağı tek şey (geleneksel olarak) bir stringssahne donanımıdır. Bileşeninizin ihtiyaç duyduğu çeşitli dizeleri içeren bir nesne olmalıdır, ancak gerçekten şekli size bağlıdır.

Varsayılan çevirileri içerir, böylece bileşeni herhangi bir çeviri sağlamaya gerek kalmadan başka bir yerde kullanabilirsiniz (kutudan çıktığı gibi varsayılan dil, bu örnekte ingilizce ile çalışır)

import { default as React, PropTypes } from 'react';
import translate from './translate';

class MyComponent extends React.Component {
    render() {

        return (
             <div>
                { this.props.strings.someTranslatedText }
             </div>
        );
    }
}

MyComponent.propTypes = {
    strings: PropTypes.object
};

MyComponent.defaultProps = {
     strings: {
         someTranslatedText: 'Hello World'
    }
};

export default translate('MyComponent')(MyComponent);

Yüksek Dereceli Bileşen

Önceki kod parçacığında, bunu son satırda fark etmiş olabilirsiniz: translate('MyComponent')(MyComponent)

translate bu durumda, bileşeninizi saran ve bazı ekstra işlevler sağlayan bir Yüksek Dereceli Bileşendir (bu yapı, önceki React sürümlerinin karışımlarının yerini alır).

İlk argüman, çeviri dosyasındaki çevirileri aramak için kullanılacak bir anahtardır (burada bileşenin adını kullandım, ancak herhangi bir şey olabilir). İkincisi (ES7 dekoratörlerine izin vermek için işlevin köreldiğine dikkat edin) Bileşenin kendisinin sarmalamasıdır.

Çeviri bileşeninin kodu:

import { default as React } from 'react';
import en from '../i18n/en';
import fr from '../i18n/fr';

const languages = {
    en,
    fr
};

export default function translate(key) {
    return Component => {
        class TranslationComponent extends React.Component {
            render() {
                console.log('current language: ', this.context.currentLanguage);
                var strings = languages[this.context.currentLanguage][key];
                return <Component {...this.props} {...this.state} strings={strings} />;
            }
        }

        TranslationComponent.contextTypes = {
            currentLanguage: React.PropTypes.string
        };

        return TranslationComponent;
    };
}

Bu sihir değil: sadece geçerli dili bağlamdan okuyacak (ve bu bağlam, kod tabanının her yerine taşmayacak, sadece burada bu sarmalayıcıda kullanıldı) ve sonra yüklenen dosyalardan ilgili dizeler nesnesini alacak. Bu mantık parçası bu örnekte oldukça saftır, gerçekten istediğiniz şekilde yapılabilir.

Önemli olan, mevcut dili bağlamdan alması ve sağlanan anahtar verildiğinde bunu dizelere dönüştürmesidir.

Hiyerarşinin en tepesinde

Kök bileşende, sadece geçerli dili mevcut durumunuzdan ayarlamanız gerekir. Aşağıdaki örnek, Flux benzeri uygulama olarak Redux kullanıyor, ancak başka herhangi bir çerçeve / desen / kitaplık kullanılarak kolayca dönüştürülebilir.

import { default as React, PropTypes } from 'react';
import Menu from '../components/Menu';
import { connect } from 'react-redux';
import { changeLanguage } from '../state/lang';

class App extends React.Component {
    render() {
        return (
            <div>
                <Menu onLanguageChange={this.props.changeLanguage}/>
                <div className="">
                    {this.props.children}
                </div>

            </div>

        );
    }

    getChildContext() {
        return {
            currentLanguage: this.props.currentLanguage
        };
    }
}

App.propTypes = {
    children: PropTypes.object.isRequired,
};

App.childContextTypes = {
    currentLanguage: PropTypes.string.isRequired
};

function select(state){
    return {user: state.auth.user, currentLanguage: state.lang.current};
}

function mapDispatchToProps(dispatch){
    return {
        changeLanguage: (lang) => dispatch(changeLanguage(lang))
    };
}

export default connect(select, mapDispatchToProps)(App);

Ve bitirmek için çeviri dosyaları:

Çeviri Dosyaları

// en.js
export default {
    MyComponent: {
        someTranslatedText: 'Hello World'
    },
    SomeOtherComponent: {
        foo: 'bar'
    }
};

// fr.js
export default {
    MyComponent: {
        someTranslatedText: 'Salut le monde'
    },
    SomeOtherComponent: {
        foo: 'bar mais en français'
    }
};

Siz ne düşünüyorsunuz?

Sanırım sorumda kaçınmaya çalıştığım tüm problemleri çözüyor: çeviri mantığı kaynak kodun her yerine yayılmıyor, oldukça izole edilmiş ve bileşenlerin onsuz yeniden kullanılmasına izin veriyor.

Örneğin, MyComponent'in translate () ile sarmalanması gerekmez ve ayrı olabilir, bu stringsda kendi imkanlarıyla sağlamak isteyen başka herhangi biri tarafından yeniden kullanılmasına izin verir .

[Düzenleme: 31/03/2016]: Yakın zamanda React & Redux ile oluşturulmuş ve çok dilli bir Retrospective Board (Çevik Retrospektifler için) üzerinde çalıştım. Pek çok insan yorumlarda gerçek hayattan bir örnek istediğinden, işte burada:

Kodu burada bulabilirsiniz: https://github.com/antoinejaussoin/retro-board/tree/master


Bu harika bir çözüm ... Birkaç ay sonra hala bu konuda olup olmadığınızı merak ediyor musunuz? Bunun çevrimiçi kalıpları hakkında tavsiye olarak fazla tavsiye bulamadım
Damon

2
Aslında ben bunun mükemmel bir şekilde çalıştığını buldum (ihtiyaçlarım için). Bileşenin varsayılan olarak çeviri olmadan çalışmasını sağlar ve çeviri, bileşen farkında olmadan onun üstüne gelir
Antoine Jaussoin

1
@ l.cetinsoy pervaneyi kullanabilirsiniz dangerouslySetInnerHTML, sadece sonuçlara dikkat edin (girişi manuel olarak sterilize edin). Bkz. Facebook.github.io/react/tips/dangerously-set-inner-html.html
Teodor Sandu

6
React-intl'i denememenizin bir nedeni var mı?
SureshCS

1
Bu çözümü gerçekten beğendim. Tutarlılık ve zaman tasarrufu için çok yararlı bulduğumuz bir şey, ortak dizelere sahip çok sayıda bileşene sahipseniz, değişkenlerden ve nesneler üzerinde yayılmadan yararlanabileceğinizdir, örneğinconst formStrings = { cancel, create, required }; export default { fooForm: { ...formStrings, foo: 'foo' }, barForm: { ...formStrings, bar: 'bar' } }
Huw Davies

18

Deneyimlerime göre, en iyi yaklaşım bir i18n redux durumu oluşturmak ve bunu birçok nedenden dolayı kullanmaktır:

1- Bu, başlangıç ​​değerini veritabanından, yerel dosyadan veya hatta EJS veya jade gibi bir şablon motorundan geçirmenize izin verecektir.

2- Kullanıcı dili değiştirdiğinde, kullanıcı arayüzünü yenilemeden bile tüm uygulama dilini değiştirebilirsiniz.

3- Kullanıcı dili değiştirdiğinde, bu aynı zamanda yeni dili API'den, yerel dosyadan ve hatta sabitlerden almanıza izin verir.

4- Saat dilimi, para birimi, yön (RTL / LTR) ve mevcut dillerin listesi gibi diğer önemli şeyleri de kaydedebilirsiniz.

5- Değişiklik dilini normal bir yeniden düzenleme işlemi olarak tanımlayabilirsiniz.

6- Arka uç ve ön uç dizelerinize tek bir yerde sahip olabilirsiniz, örneğin benim durumumda yerelleştirme için i18n-node kullanıyorum ve kullanıcı UI dilini değiştirdiğinde sadece normal bir API çağrısı yapıyorum ve arka uçta sadece geri dönüyorumi18n.getCatalog(req) bu sadece mevcut dil için tüm kullanıcı dizelerini döndürecektir

İ18n ilk durumu için önerim şu:

{
  "language":"ar",
  "availableLanguages":[
    {"code":"en","name": "English"},
    {"code":"ar","name":"عربي"}
  ],
  "catalog":[
     "Hello":"مرحباً",
     "Thank You":"شكراً",
     "You have {count} new messages":"لديك {count} رسائل جديدة"
   ],
  "timezone":"",
  "currency":"",
  "direction":"rtl",
}

İ18n için ekstra kullanışlı modüller:

1- string-template bu, katalog dizeleriniz arasına değerler enjekte etmenize izin verir, örneğin:

import template from "string-template";
const count = 7;
//....
template(i18n.catalog["You have {count} new messages"],{count}) // لديك ٧ رسائل جديدة

2- insan biçiminde bu modül, bir sayıyı insan tarafından okunabilir bir dizeye / dizeden dönüştürmenize olanak tanır, örneğin:

import humanFormat from "human-format";
//...
humanFormat(1337); // => '1.34 k'
// you can pass your own translated scale, e.g: humanFormat(1337,MyScale)

3- momentjs en ünlü tarihler ve saatler npm kitaplığıdır, anı çevirebilirsiniz, ancak zaten yerleşik bir çevirisi vardır, yalnızca mevcut durum dilini geçmeniz gerekir, örneğin:

import moment from "moment";

const umoment = moment().locale(i18n.language);
umoment.format('MMMM Do YYYY, h:mm:ss a'); // أيار مايو ٢ ٢٠١٧، ٥:١٩:٥٥ م

Güncelleme (14/06/2019)

Şu anda, react context API (redux olmadan) kullanarak aynı konsepti uygulayan birçok çerçeve var, ben şahsen I18next'i önerdim


Bu yaklaşım ikiden fazla dil için de işe yarar mı? Kataloğun kurulumunu ele
alırken

Olumsuz oy verildi. Bu soruya cevap vermiyor. OP, herhangi bir i18n kitaplığında bir öneri veya karşılaştırma değil, bir mimari fikir istedi.
TrungDQ

9
İ18n kataloğunu redux durumu olarak
önerdim,

5

Antoine'ın çözümü iyi çalışıyor, ancak bazı uyarılar var:

  • Redux kullanırken kaçınmaya eğilimli olduğum React bağlamını doğrudan kullanıyor
  • İfadeleri doğrudan bir dosyadan içe aktarır; bu, çalışma zamanında, istemci tarafında gerekli dili getirmek istiyorsanız sorunlu olabilir.
  • Hafif olan ancak çoğullaştırma ve enterpolasyon gibi kullanışlı çeviri işlevlerine erişim sağlamayan herhangi bir i18n kitaplığı kullanmaz

Bu nedenle hem Redux hem de AirBNB Polyglot üzerine redux-polyglot oluşturduk . (Ben yazarlardan biriyim)

Şunları sağlar:

  • Redux mağazanızda dili ve ilgili mesajları depolamak için bir azaltıcı. Her ikisini de şu şekilde tedarik edebilirsiniz:
    • belirli bir eylemi yakalamak, mevcut dili çıkarmak ve ilişkili mesajları almak / getirmek için yapılandırabileceğiniz bir ara yazılım.
    • doğrudan sevkiyat setLanguage(lang, messages)
  • 4 yöntemi ortaya çıkaran getP(state)bir Pnesneyi alan bir seçici :
    • t(key): orijinal çok dilli T işlevi
    • tc(key): büyük harfle yazılmış çeviri
    • tu(key): büyük harfli çeviri
    • tm(morphism)(key): özel biçimlendirilmiş çeviri
  • getLocale(state)mevcut dili almak için bir seçici
  • Bir translateyüksek mertebeden bileşeni enjekte ederek senin bileşenleri Tepki geliştirmek için psahne nesne

Basit kullanım örneği:

yeni dil gönder:

import setLanguage from 'redux-polyglot/setLanguage';

store.dispatch(setLanguage('en', {
    common: { hello_world: 'Hello world' } } }
}));

bileşende:

import React, { PropTypes } from 'react';
import translate from 'redux-polyglot/translate';

const MyComponent = props => (
  <div className='someId'>
    {props.p.t('common.hello_world')}
  </div>
);
MyComponent.propTypes = {
  p: PropTypes.shape({t: PropTypes.func.isRequired}).isRequired,
}
export default translate(MyComponent);

Herhangi bir sorunuz / öneriniz varsa lütfen bana bildirin!


1
Çevrilecek çok daha iyi orijinal ifadeler. Ve _()işlevler için tüm bileşenleri ayrıştıran bir araç yapmak , örneğin tüm bu dizeleri almak için. Böylece, dil dosyasında daha kolay tercüme edebilir ve çılgın değişkenlerle uğraşmayın. Bazı durumlarda, açılış sayfalarının farklı şekilde gösterilmesi için belirli bir düzen parçasına ihtiyaç vardır. Bu nedenle, diğer olası seçeneklere karşı varsayılanı seçme konusunda bazı akıllı işlevler de mevcut olmalıdır.
Roman M. Koss

Merhaba @ Jalil, herhangi bir ara yazılım ile eksiksiz bir örnek var mı?
ArkadyB

Merhaba @ArkadyB, Açık kaynaklı olmayan birkaç projede üretimde kullanıyoruz. README modülü hakkında daha fazla bilgi bulabilirsiniz: npmjs.com/package/redux-polyglot Bunu kullanırken herhangi bir sorunuz / zorluğunuz var mı?
Jalil

Bu ve polyglot.js ile ilgili en büyük sorunum, PO dosyalarının üzerine inşa etmek yerine tekerleği tamamen yeniden icat etmesidir. Bu alternatif kitaplık, npmjs.com/package/redux-i18n için umut verici görünüyor . Bunun çok farklı olduğunu düşünmüyorum - sadece PO dosyalarına ve PO dosyalarına dönüştürmek için fazladan bir katman sağlıyor.
icc97

2

Bu konudaki araştırmamdan, JavaScript, ICU ve gettext'te i18n için kullanılan iki ana yaklaşım var gibi görünüyor .

Sadece gettext kullandım, bu yüzden önyargılıyım.

Beni şaşırtan, desteğin ne kadar zayıf olduğu. PHP dünyasından geliyorum, CakePHP veya WordPress. Her iki durumda da, tüm dizelerin basitçe çevrelenmesi temel bir standarttır __(''), daha sonra PO dosyalarını kullanarak çevirileri çok kolay bir şekilde alırsınız.

gettext'lerle

Dizeleri biçimlendirmek için sprintf'e aşinalık elde edersiniz ve PO dosyaları binlerce farklı ajans tarafından kolayca çevrilir.

İki popüler seçenek var:

  1. i18next , bu arkency.com blog gönderisinde açıklanan kullanımla
  2. Sentry.io gönderisi ve bu React + Redux gönderisi tarafından açıklanan kullanımla Jed ,

Her ikisi de gettext stili desteğine, dizelerin sprintf stili biçimlendirmesine ve PO dosyalarına içe / dışa aktarmaya sahiptir.

i18next'in kendi geliştirdiği bir React uzantısı vardır . Jed yapmaz. Sentry.io, Jed'in React ile özel bir entegrasyonunu kullanıyor gibi görünüyor. + Redux yayını tepki , kullanılmasını önermektedir

Araçlar: jed + po2json + jsxgettext

Bununla birlikte, Jed daha çok gettext odaklı bir uygulama gibi görünüyor - bu, ifade edilen niyettir, burada i18next'de bir seçenek olarak bulunur.

Yoğun bakım

Bu, çevirilerle ilgili uç vakalar için, örneğin cinsiyetle ilgilenme konusunda daha fazla destek sağlıyor. Çevrilecek daha karmaşık dilleriniz varsa bunun faydalarını göreceğinizi düşünüyorum.

Bunun için popüler bir seçenek, messageformat.js'dir . Bu sentry.io blog eğitiminde kısaca tartışıldı . messageformat.js aslında Jed'i yazan kişi tarafından geliştirilmiştir. YBÜ kullanmak için oldukça güçlü iddialarda bulunuyor :

Bence Jed tam bir özellik. Hataları düzeltmekten mutluyum, ancak genellikle kitaplığa daha fazlasını eklemekle ilgilenmiyorum.

Ayrıca messageformat.js'yi de sürdürüyorum. Özellikle bir gettext uygulamasına ihtiyacınız yoksa, çoğullar / cinsiyet için daha iyi desteğe sahip olduğu ve yerleşik yerel verileri içerdiği için bunun yerine MessageFormat kullanmanızı önerebilirim.

Kaba karşılaştırma

sprintf ile gettext:

i18next.t('Hello world!');
i18next.t(
    'The first 4 letters of the english alphabet are: %s, %s, %s and %s', 
    { postProcess: 'sprintf', sprintf: ['a', 'b', 'c', 'd'] }
);

messageformat.js ( kılavuzu okurken en iyi tahminim ):

mf.compile('Hello world!')();
mf.compile(
    'The first 4 letters of the english alphabet are: {s1}, {s2}, {s3} and {s4}'
)({ s1: 'a', s2: 'b', s3: 'c', s4: 'd' });

Olumsuz oy verildi. Bu soruya cevap vermiyor. OP, herhangi bir i18n kitaplığında bir öneri veya karşılaştırma değil, bir mimari fikir istedi.
TrungDQ

@TrungDQ OP'nin sorduğu şey buydu: "Sorum tamamen teknik değil, daha çok mimari ve insanların bu sorunu çözmek için üretimde kullandıkları kalıplarla ilgili." . Bunlar üretimde kullanılan iki modeldir.
icc97

Kanımca bu cevap, aradığım (ve başkalarının) bilgiyi sağlamıyor. Sağladığınız bilgiler yardımcı olabilir, ancak belki başka bir soru için. Sadece doğru cevabın en üste çıkması için olumsuz oyuma katkıda bulunmak istiyorum (umarım).
TrungDQ

@TrungDQ Aradığınız şey bu değilse, ilgilendiğiniz sorunun belirli kısmıyla eşleşmeyen tamamen geçerli yanıtları olumsuz oylamak yerine, kullandığınız soruyu destekleyin ve diğerlerini göz ardı edin.
icc97

1

Henüz https://react.i18next.com/ adresine bir göz atmadıysanız iyi bir tavsiye olabilir. İ18next'e dayanır: Bir kez öğrenin - her yerde tercüme edin.

Kodunuz şuna benzer:

<div>{t('simpleContent')}</div>
<Trans i18nKey="userMessagesUnread" count={count}>
  Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>

Aşağıdakiler için örneklerle birlikte gelir:

  • webpack
  • cra
  • expo.js
  • next.js
  • hikaye kitabı entegrasyonu
  • razzle
  • dat
  • ...

https://github.com/i18next/react-i18next/tree/master/example

Bunun yanı sıra, geliştirme sırasında ve daha sonra çevirmenleriniz için iş akışını da düşünmelisiniz -> https://www.youtube.com/watch?v=9NOzJhgmyQE


Bu soruya cevap vermiyor. OP, herhangi bir i18n kitaplığında bir öneri veya karşılaştırma değil, bir mimari fikir istedi.
TrungDQ

@TrungDQ, olumsuz oy verdiğiniz cevabım hakkındaki yorumunuzda olduğu gibi - OP, üretimde kullanılan mevcut çözümleri istedi. Ancak içinde i18next öne sürmüştü benim cevap Şubat arkadan gelen
icc97

0

Create-react-app kullanarak basit bir çözüm önermek istiyorum .

Uygulama her dil için ayrı ayrı oluşturulacak, bu nedenle tüm çeviri mantığı uygulamadan çıkarılacaktır.

Web sunucusu, Accept-Language başlığına bağlı olarak doğru dili otomatik olarak veya bir tanımlama bilgisi ayarlayarak manuel olarak sunacaktır .

Çoğunlukla dili bir kereden fazla değiştirmiyoruz, hiç değilse)

Çeviri verileri, onu kullanan aynı bileşen dosyasına stiller, html ve kodla birlikte yerleştirilir.

Ve burada, kendi durumundan, görüşünden, çevirisinden sorumlu olan tamamen bağımsız bir bileşene sahibiz:

import React from 'react';
import {withStyles} from 'material-ui/styles';
import {languageForm} from './common-language';
const {REACT_APP_LANGUAGE: LANGUAGE} = process.env;
export let language; // define and export language if you wish
class Component extends React.Component {
    render() {
        return (
            <div className={this.props.classes.someStyle}>
                <h2>{language.title}</h2>
                <p>{language.description}</p>
                <p>{language.amount}</p>
                <button>{languageForm.save}</button>
            </div>
        );
    }
}
const styles = theme => ({
    someStyle: {padding: 10},
});
export default withStyles(styles)(Component);
// sets laguage at build time
language = (
    LANGUAGE === 'ru' ? { // Russian
        title: 'Транзакции',
        description: 'Описание',
        amount: 'Сумма',
    } :
    LANGUAGE === 'ee' ? { // Estonian
        title: 'Tehingud',
        description: 'Kirjeldus',
        amount: 'Summa',
    } :
    { // default language // English
        title: 'Transactions',
        description: 'Description',
        amount: 'Sum',
    }
);

Package.json dosyanıza dil ortamı değişkeni ekleyin

"start": "REACT_APP_LANGUAGE=ru npm-run-all -p watch-css start-js",
"build": "REACT_APP_LANGUAGE=ru npm-run-all build-css build-js",

İşte bu!

Ayrıca orijinal cevabım, her çeviri için tek bir json dosyasıyla daha monolitik bir yaklaşım içeriyordu:

lang / ru.json

{"hello": "Привет"}

lib / lang.js

export default require(`../lang/${process.env.REACT_APP_LANGUAGE}.json`);

src / App.jsx

import lang from '../lib/lang.js';
console.log(lang.hello);

Sadece derleme zamanında çalışmaz mı? Kullanıcının dili anında değiştirme yeteneği olmadan mı? O zaman bu farklı bir kullanım durumu olacaktır.
Antoine Jaussoin

Uygulama, ihtiyaç duyulan her dil için derlenecektir. Web sunucusu, "Accept-Language" başlığına bağlı olarak veya kullanıcı tarafından anında ayarlanan bir tanımlama bilgisine bağlı olarak doğru sürümü otomatik olarak sunacaktır. Bunu yaparak, tüm çeviri mantığı uygulamanın dışına taşınabilir.
Igor Sukharev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.