काफी कुछ समाधानों की कोशिश करने के बाद, मुझे लगता है कि मैंने एक ऐसा पाया जो अच्छी तरह से काम करता है और रिएक्ट 0.14 के लिए एक मुहावरेदार समाधान होना चाहिए (अर्थात यह मिश्रण का उपयोग नहीं करता है, लेकिन उच्च आदेश घटक) ( संपादित करें : पाठ्यक्रम के रिएक्ट 15 के साथ भी पूरी तरह से ठीक है! )।
तो यहाँ समाधान, नीचे से शुरू (व्यक्तिगत घटकों):
घटक
केवल एक चीज की आपके घटक को (सम्मेलन द्वारा) आवश्यकता होगी, एक strings
सहारा है। यह एक ऐसी वस्तु होनी चाहिए जिसमें आपके कंपोनेंट की जरूरत के विभिन्न तार हों, लेकिन वास्तव में इसका आकार आपके ऊपर है।
इसमें डिफ़ॉल्ट अनुवाद शामिल हैं, इसलिए आप किसी भी अनुवाद को प्रदान करने की आवश्यकता के बिना घटक का उपयोग कहीं और कर सकते हैं (यह डिफ़ॉल्ट भाषा के साथ बॉक्स से बाहर काम करेगा, इस उदाहरण में अंग्रेजी)
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);
उच्चतर आदेश घटक
पिछले स्निपेट पर, आपने इसे अंतिम पंक्ति पर देखा होगा:
translate('MyComponent')(MyComponent)
translate
इस मामले में एक उच्च आदेश घटक है जो आपके घटक को लपेटता है, और कुछ अतिरिक्त कार्यक्षमता प्रदान करता है (यह निर्माण प्रतिक्रिया के पिछले संस्करणों के मिश्रण को बदल देता है)।
पहला तर्क एक कुंजी है जिसका उपयोग अनुवाद फ़ाइल में अनुवाद देखने के लिए किया जाएगा (मैंने यहां घटक के नाम का उपयोग किया था, लेकिन यह कुछ भी हो सकता है)। दूसरा एक (नोटिस कि फ़ंक्शन करी है, ES7 सज्जाकार की अनुमति देने के लिए) लपेटने के लिए घटक है।
यहाँ अनुवाद घटक के लिए कोड है:
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;
};
}
यह जादू नहीं है: यह सिर्फ संदर्भ से वर्तमान भाषा को पढ़ेगा (और यह संदर्भ कोड आधार पर पूरी तरह से खून नहीं करता है, बस यहां इस आवरण में उपयोग किया जाता है), और फिर लोड की गई फ़ाइलों से संबंधित स्ट्रिंग ऑब्जेक्ट प्राप्त करें। तर्क का यह टुकड़ा इस उदाहरण में काफी भोला है, जिस तरह से आप वास्तव में चाहते हैं।
महत्वपूर्ण टुकड़ा यह है कि यह वर्तमान भाषा को संदर्भ से लेता है और प्रदान की गई कुंजी को देखते हुए इसे तार में परिवर्तित करता है।
पदानुक्रम के शीर्ष पर
रूट घटक पर, आपको बस अपनी वर्तमान स्थिति से वर्तमान भाषा सेट करने की आवश्यकता है। निम्न उदाहरण फ्लक्स जैसे कार्यान्वयन के रूप में Redux का उपयोग कर रहा है, लेकिन इसे आसानी से किसी अन्य ढांचे / पैटर्न / लाइब्रेरी का उपयोग करके परिवर्तित किया जा सकता है।
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);
और अनुवाद फ़ाइलों को पूरा करने के लिए:
अनुवाद फ़ाइलें
// 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'
}
};
आप लोग क्या सोचते हैं?
मुझे लगता है कि मैं अपने सवाल से बचने की कोशिश कर रहा था कि सभी समस्या का हल हो रहा है: अनुवाद तर्क स्रोत कोड पर पूरी तरह से खून नहीं करता है, यह काफी अलग-थलग है और इसके बिना घटकों का पुन: उपयोग करने की अनुमति देता है।
उदाहरण के लिए, MyComponent को अनुवाद द्वारा लिपटा जाने की आवश्यकता नहीं है (और अलग किया जा सकता है, यह अनुमति देता है कि यह किसी और के द्वारा फिर से उपयोग करने के लिए strings
अपने स्वयं के माध्यम से प्रदान करना चाहता है।
[संपादित करें: ३१/०३/२०१६]: मैंने हाल ही में एक रेट्रोस्पेक्टिव बोर्ड (एजाइल रेट्रोस्पेक्टिव्स के लिए) पर काम किया, जो रिएक्ट एंड रेडक्स के साथ बनाया गया है, और बहुभाषी है। चूंकि काफी लोगों ने टिप्पणियों में वास्तविक जीवन का उदाहरण मांगा है, इसलिए यह है:
आप यहां कोड पा सकते हैं: https://github.com/antoinejaussoin/retro-board/tree/master