Как использовать Ant Design LocaleProvider с React-Boilerplate
Мы начали использовать этот React-Boilerplate. Также мы пытаемся интегрировать Ant Design для его потрясающих компонентов.
Из документов Ant Design я создал оболочку для AppWrapper из React-шаблон, как это -
import { LocaleProvider } from 'antd';
import enUS from 'antd/lib/locale-provider/en_US';
return (
<LocaleProvider locale={enUS}>
<AppWrapper>
...
</AppWrapper>
</LocaleProvider>
);
И он отлично работает для компонентов и.
Я хотел знать, как я могу использовать это с i18n реактивного образца. Или если вышеуказанный способ является правильным способом сделать это?
2 ответа
В общем, это правильный способ использования LocaleProvider, да, но...
Вы должны быть осторожны при смешивании оболочки библиотек i18n с LocaleProvider из antd, если хотите, чтобы изменения языка распространялись на оба.
В случае React-Boilerplate локаль хранится в Redux. Чтобы antd мог обновлять локаль, когда приложение это делает, <LocaleProvider>
должен быть вставлен в провайдера Redux, иначе он не будет иметь доступа к состоянию локали.
Так что ваши app.js
должен стать чем-то вроде:
<Provider store={store}>
<LanguageProvider messages={messages}>
<LocaleProvider locale={...}>
<Router ... />
</LocaleProvider>
</LanguageProvider>
</Provider>,
К сожалению, этого недостаточно, так как LocaleProvider в antd принимает в качестве аргумента не простую строку идентификатора локали, а объект с самой информацией о локали.
Это означает, что невозможно просто вставить <LocaleProvider>
в цепи обмотки, как указано выше. Вы должны создать свой собственный компонент, который соединяется с пропуском локали Redux и кормит <LocaleProvider>
с правильным объектом локали на основе идентификатора строки из Redux.
Вот некоторый (непроверенный) код, который я вырвал из проекта с похожей структурой и адаптировал к Intl (он использовал i18next вместо Intl). Должен дать вам представление о том, как это сделать.
import React from 'react';
import { Router } from 'react-router';
import { Provider, connect } from 'react-redux';
import en_US from 'antd/lib/locale-provider/en_US';
import sv_SE from 'antd/lib/locale-provider/sv_SE';
import { LocaleProvidern } from 'antd';
class AntDesignPlusRouter extends React.Component {
state = {
antd_locale: en_US
}
componentWillUpdate( next ) {
let { locale } = next
if( !locale || locale === this.props.locale ) return;
switch( locale ) {
case 'sv':
this.setState( { antd_locale: sv_SE } );
break;
default:
case 'en':
this.setState( { antd_locale: en_US } );
break;
}
}
render() {
return (
<LocaleProvider locale={this.state.antd_locale}>
<Router {...this.props} />
</LocaleProvider>
)
}
}
const WrappedAntDesignPlusRouter = connect(
function mapStateToProps( state ) {
return {
locale: state.locale
}
},
function mapDispatchToProps( dispatch ) {
return {}
}
)( AntDesignPlusRouter );
class App extends React.Component {
render() {
return (
<Provider ...>
<LanguageProvider ...>
<WrappedAntDesignPlusRouter/>
</LanguageProvider >
</Provider>
);
}
}
для меня это сработало, поскольку localprovider устарел, а configprovider заменен на
Изменения, внесенные в приведенный ниже фрагмент кода
Неделя должна начинаться с понедельника
день изменился с понедельника на понедельник
импортировать {Calendar, ConfigProvider} из antd; импортировать en_GB из 'antd / lib / locale-provider / en_GB'; момент импорта из «момента»; import 'момент / локаль / en-gb'; импортировать React из React;import './scheduler.scss';
const Scheduler = () => { moment.locale('en-gb'); // important! moment.updateLocale('en', { weekdaysMin: ["M", "T", "W", "T", "F", "S", "S"] }); return ( <div class='scheduler-dashboard'> <ConfigProvider locale={en_GB}> <Calendar /> </ConfigProvider > </div> ); }; export default Scheduler;