Raf*_*ado 10 javascript ecmascript-6 reactjs react-intl create-react-app
我正试图弄清楚如何使用React-Intl更改语言.这是我的第一个React App,它是用create-react-app制作的,我没有使用Redux和Flux.
在我的index.js中,我有以下代码:
import React from 'react';
import ReactDOM from 'react-dom';
import TodoApp from './components/TodoApp';
import registerServiceWorker from './registerServiceWorker';
import './index.css';
// Bootstrap CSS libraries
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import { IntlProvider, addLocaleData } from 'react-intl';
import intlEN from 'react-intl/locale-data/en';
import intlES from 'react-intl/locale-data/es';
import intlMessagesES from './i18n/locales/es.json';
import intlMessagesEN from './i18n/locales/en.json';
addLocaleData([...intlEN, ...intlES]);
/* Define your translations */
let i18nConfig = {
locale: 'es',
messages: intlMessagesES
};
let changeLanguage = (lang) => {
i18nConfig = { locale: lang, messages: intlMessagesEN };
return i18nConfig;
}
ReactDOM.render(
<IntlProvider locale={ i18nConfig.locale } key={ i18nConfig.locale } messages={ i18nConfig.messages }>
<TodoApp onChangeLanguage={changeLanguage} />
</IntlProvider>,
document.getElementById('root'));
registerServiceWorker();
Run Code Online (Sandbox Code Playgroud)
TodoApp通过道具发送'lang'参数的字符串(即:'es'或'en'),当我改变i18nConfig时,IntlProvider似乎没有任何改变.我的想法是改变我的i18nConfig变量,然后我的所有应用程序也会改变语言.
我在TodoApp中有FormattedMessages,我的两条JSON消息填充如下:
// i18n/locales/en.json
{
"footer.add.placeholder": "Enter a name ...",
"footer.add.priority0.text": "No priority",
"footer.add.priority1.text": "Priority 1",
...
}
Run Code Online (Sandbox Code Playgroud)
你知道我的代码中缺少什么吗?也许我对React-Intl一无所知.任何建议都会有所帮助,谢谢.
Raf*_*ado 14
如果你从root删除所有它:
ReactDOM.render(<TodoApp />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
但现在我们改变TodoApp组件如下:
1)我们将'locale'添加为组件状态并导入React-Intl:
import { IntlProvider, addLocaleData } from 'react-intl';
import intlEN from 'react-intl/locale-data/en';
import intlES from 'react-intl/locale-data/es';
import intlMessagesES from './../i18n/locales/es.json';
import intlMessagesEN from './../i18n/locales/en.json';
addLocaleData([...intlEN, ...intlES]);
/* Define your default translations */
let i18nConfig = {
locale: 'en',
messages: intlMessagesEN
};
Run Code Online (Sandbox Code Playgroud)
2)更改我们的changeLanguage函数(这次称为'onChangeLanguage'),此函数从subComponent语言选择器接收'lang':
onChangeLanguage(lang) {
switch (lang) {
case 'ES': i18nConfig.messages = intlMessagesES; break;
case 'EN': i18nConfig.messages = intlMessagesEN; break;
default: i18nConfig.messages = intlMessagesEN; break;
}
this.setState({ locale: lang });
i18nConfig.locale = lang;
}
Run Code Online (Sandbox Code Playgroud)
最后渲染:
render() {
return (
<IntlProvider key={ i18nConfig.locale } locale={ i18nConfig.locale } messages={ i18nConfig.messages }>
<div>
<Header onChangeLanguage={this.onChangeLanguage} />
// Other components ...
</div>
</IntlProvider>
);
}
Run Code Online (Sandbox Code Playgroud)
如果有人根本不理解,请在评论中提问!感谢@TomásEhrich
使用新的React Context API,它很容易实现.创建一个包装器:
import React from "react";
import Types from "prop-types";
import { IntlProvider, addLocaleData } from "react-intl";
import en from "react-intl/locale-data/en";
import de from "react-intl/locale-data/de";
import deTranslation from "../../lang/de";
import enTranslation from "../../lang/en";
addLocaleData([...en, ...de]);
const Context = React.createContext();
class IntlProviderWrapper extends React.Component {
constructor(...args) {
super(...args);
this.switchToEnglish = () =>
this.setState({ locale: "en", messages: enTranslation });
this.switchToDeutsch = () =>
this.setState({ locale: "de", messages: deTranslation });
// pass everything in state to avoid creating object inside render method (like explained in the documentation)
this.state = {
locale: "en",
messages: enTranslation,
switchToEnglish: this.switchToEnglish,
switchToDeutsch: this.switchToDeutsch
};
}
render() {
const { children } = this.props;
const { locale, messages } = this.state;
return (
<Context.Provider value={this.state}>
<IntlProvider
key={locale}
locale={locale}
messages={messages}
defaultLocale="en"
>
{children}
</IntlProvider>
</Context.Provider>
);
}
}
export { IntlProviderWrapper, Context as IntlContext };
Run Code Online (Sandbox Code Playgroud)
然后使用提供者和消费者:
import { Provider } from "react-redux";
import { IntlProviderWrapper } from "./IntlContext";
class App extends Component {
render() {
return (
<Provider store={store}>
<IntlProviderWrapper>
...
</IntlProviderWrapper>
</Provider>
);
}
}
Run Code Online (Sandbox Code Playgroud)
在应用程序的某个地方:
import React from "react";
import { Text, Button } from "native-base";
import { IntlContext } from "../IntlContext";
const LanguageSwitch = () => (
<IntlContext.Consumer>
{({ switchToEnglish, switchToDeutsch }) => (
<React.Fragment>
<button onClick={switchToEnglish}>
English
</button>
<button onClick={switchToDeutsch}>
Deutsch
</button>
</React.Fragment>
)}
</IntlContext.Consumer>
);
// with hooks
const LanguageSwitch2 = () => {
const { switchToEnglish, switchToDeutsch } = React.useContext(IntlContext);
return (
<>
<button onClick={switchToEnglish}>English</button>
<button onClick={switchToDeutsch}>Deutsch</button>
</>
);
};
export default LanguageSwitch;
Run Code Online (Sandbox Code Playgroud)
以下是具有更一般解决方案的相关存储库.
注意:目前,react-intl仍在使用旧的上下文API,但在未来的解决方案中,这样的解决方案可能是开箱即用的.
| 归档时间: |
|
| 查看次数: |
14679 次 |
| 最近记录: |