qwe*_*asd 11 internationalization reactjs formatjs react-intl
我有react-router app并且想添加i18n.在react-intl 示例中,IntlProvider中包含的根组件:
ReactDOM.render(
<IntlProvider locale="en">
<App />
</IntlProvider>,
document.getElementById('container')
Run Code Online (Sandbox Code Playgroud)
);
但是只有一个区域设置.如何更新应用程序以添加其他语言以及如何存储翻译的最佳方式?
小智 19
我遇到了同样的问题,这就是我发现的:
为了改变语言,我使用了这里提供的解决方案,它基本上将IntlProvider绑定到具有Connect功能的ReduxStore.另外,不要忘记在语言更改时包含重新呈现组件的键.这基本上都是所有代码:
这是ConnectedIntlProvider.js,只是绑定默认的IntlProvider(注意github上原始注释中缺少的关键prop)
import { connect } from 'react-redux';
import { IntlProvider } from 'react-intl';
// This function will map the current redux state to the props for the component that it is "connected" to.
// When the state of the redux store changes, this function will be called, if the props that come out of
// this function are different, then the component that is wrapped is re-rendered.
function mapStateToProps(state) {
const { lang, messages } = state.locales;
return { locale: lang, key: lang, messages };
}
export default connect(mapStateToProps)(IntlProvider);
Run Code Online (Sandbox Code Playgroud)
然后在您的入口点文件中:
// index.js (your top-level file)
import ConnectedIntlProvider from 'ConnectedIntlProvider';
const store = applyMiddleware(thunkMiddleware)(createStore)(reducers);
ReactDOM.render((
<Provider store={store}>
<ConnectedIntlProvider>
<Router history={createHistory()}>{routes}</Router>
</ConnectedIntlProvider>
</Provider>
), document.getElementById( APP_DOM_CONTAINER ));
Run Code Online (Sandbox Code Playgroud)
接下来要做的就是实现reducer来管理语言环境,并让动作创建者按需更改语言.
至于存储翻译的最佳方式 - 我发现很多关于这个主题的讨论和情况似乎很混乱,老实说,我很反感,react-intl的制作者如此关注日期和数字格式而忘记翻译.所以,我不知道处理它的绝对正确的方法,但这就是我所做的:
创建文件夹"locales"并在里面创建一堆文件,如"en.js","fi.js","ru.js"等.基本上所有使用的语言.
在每个文件中导出json对象,其翻译如下:
export const ENGLISH_STATE = {
lang: 'en',
messages: {
'app.header.title': 'Awesome site',
'app.header.subtitle': 'check it out',
'app.header.about': 'About',
'app.header.services': 'services',
'app.header.shipping': 'Shipping & Payment',
}
}
Run Code Online (Sandbox Code Playgroud)
其他文件具有完全相同的结构,但内部已翻译字符串.
然后在负责语言更改的reducer中,从这些文件导入所有状态,并在调度更改语言的操作后立即将它们加载到redux存储中.在上一步中创建的组件会将更改传播到IntlProvider,并且将发生新的语言环境.使用<FormattedMessage>
或在页面上输出,或者intl.formatMessage({id: 'app.header.title'})}
在github wiki上阅读更多内容.
他们在那里有一些DefineMessages功能,但老实说,我找不到任何好的信息如何使用它,基本上你可以忘记它并且没问题.
我相信有了新的Context API,现在不需要使用redux了:
IntlContext.jsx
import React from "react";
import { IntlProvider, addLocaleData } from "react-intl";
import en from "react-intl/locale-data/en";
import de from "react-intl/locale-data/de";
const deTranslation = {
//...
};
const enTranslation = {
//...
};
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)
App.jsx主要组件:
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)
LanguageSwitch.jsx
import React from "react";
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)
我创建了一个展示该想法的存储库。还有codeandbox示例。
归档时间: |
|
查看次数: |
12468 次 |
最近记录: |