Добавить локализацию и перевод в приложение React с помощью redux (без i18next)
Локализация — это процесс перевода вашего приложения на разные языки. В этой статье мы узнаем, как добавить поддержку локализации в приложение React с помощью Redux и Ant Design без использования react-i18next.
Посмотрите видео на YouTube:
Шаг 1: Настройка Redux
Сначала давайте настроим Redux
в нашем приложении React
. Если вы еще этого не сделали, установите необходимые зависимости:
npm install redux react-redux
Затем создайте новый файл с именем store.js
и импортируйте необходимые модули Redux:
import { createStore } from 'redux';
import { Provider } from 'react-redux';
Создайте функцию Action
для обработки состояния локализации:
import * as actionTypes from './types';
import languages from '@/locale/languages';
async function fetchTranslation() {
try {
let translation = await import('@/locale/translation/translation');
return translation.default;
} catch (error) {
console.error(
'Error fetching translation file :~ file: actions.js:7 ~ fetchTranslation ~ fetchTranslation:',
error
);
}
}
export const translateAction = {
resetState: () => (dispatch) => {
dispatch({
type: actionTypes.RESET_STATE,
});
},
translate: (value) => async (dispatch) => {
dispatch({
type: actionTypes.REQUEST_LOADING,
});
const translation = await fetchTranslation();
let data = await translation[value];
const isRtl = languages.find((l) => l.value === value).isRtl || false;
const LANG_STATE = {
result: data,
isRtl: isRtl,
langDirection: isRtl ? 'rtl' : 'ltr',
langCode: value,
isLoading: false,
isSuccess: false,
};
window.localStorage.setItem('translate', JSON.stringify(LANG_STATE));
if (data) {
dispatch({
type: actionTypes.REQUEST_SUCCESS,
payload: data,
langCode: value,
isRtl: isRtl,
});
} else {
dispatch({
type: actionTypes.REQUEST_FAILED,
});
}
},
};
Создайте хранилище Redux с помощью редуктора:
const store = createStore(localizationReducer);
Оберните корневой компонент компонентом Provider
из react-redux
, передав хранилище Redux в качестве реквизита:
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Шаг 2. Установите Ant Design
Установите Ant Design
, выполнив следующую команду:
npm install antd
Импортируйте необходимые компоненты из Ant Design
в нужный вам компонент:
import { ConfigProvider, Button } from 'antd';
import { useSelector, useDispatch } from 'react-redux';
Настройте Ant Design для использования правильной locale
, добавив следующий код в верхней части вашего компонента:
const { locale } = useSelector((state) => state.localization);
const dispatch = useDispatch();
Шаг 3. Создайте языковые файлы
Создайте языковые файлы для каждого поддерживаемого языка в каталоге с именем locales
. Например, создайте файл en.js
со следующим содержимым:
export default {
edit: "Modifier",
save: "Sauvegarder",
cancel: "Annuler",
delete: "Supprimer",
create: "Créer",
update: "Mettre à jour",
search: "Rechercher",
select: "Sélectionner",
view: "Voir",
submit: "Soumettre",
add: "Ajouter",
...
}
Создайте аналогичный файл для других языков. Обязательно экспортируйте переводы как объект.
Шаг 4. Внедрение компонента перевода
Создайте новые хуки под названием useLanguage
:
import { useSelector } from 'react-redux';
import { selectCurrentLang } from '@/redux/translate/selectors';
const getLabel = (lang, key) => {
try {
const lowerCaseKey = key
.toLowerCase()
.replace(/[^a-zA-Z0-9]/g, '_')
.replace(/ /g, '_');
if (lang[lowerCaseKey]) return lang[lowerCaseKey];
else {
// convert no found language label key to label
const remove_underscore_fromKey = lowerCaseKey.replace(/_/g, ' ').split(' ');
const conversionOfAllFirstCharacterofEachWord = remove_underscore_fromKey.map(
(word) => word[0].toUpperCase() + word.substring(1)
);
const label = conversionOfAllFirstCharacterofEachWord.join(' ');
const result = window.localStorage.getItem('lang');
if (!result) {
let list = {};
list[lowerCaseKey] = label;
window.localStorage.setItem('lang', JSON.stringify(list));
} else {
let list = { ...JSON.parse(result) };
list[lowerCaseKey] = label;
window.localStorage.removeItem('lang');
window.localStorage.setItem('lang', JSON.stringify(list));
}
return label;
}
} catch (error) {
return 'No translate';
}
};
const useLanguage = () => {
const lang = useSelector(selectCurrentLang);
const translate = (value) => getLabel(lang, value);
return translate;
};
export default useLanguage;
Шаг 5. Соедините Redux и Ant Design
В вашем основном компоненте приложения импортируйте компонент Translation
и визуализируйте его в компоненте ConfigProvider
из Ant Design
:
import { useDispatch, useSelector } from 'react-redux';
import languages from '@/locale/languages';
import { selectLangCode } from '@/redux/translate/selectors';
import { translateAction } from '@/redux/translate/actions';
import useLanguage from '@/locale/useLanguage';
import { Select } from 'antd';
const SelectLanguage = () => {
const translate = useLanguage();
const dispatch = useDispatch();
const langCode = useSelector(selectLangCode);
return (
<>
<label
htmlFor="rc_select_1"
className="hiddenLabel"
style={{
width: '0px',
marginRight: '-20px',
position: 'relative',
}}
>
_
</label>
<Select
showSearch
placeholder={translate('select language')}
value={langCode}
defaultOpen={false}
style={{
width: '120px',
float: 'right',
marginTop: '5px',
cursor: 'pointer',
}}
optionFilterProp="children"
filterOption={(input, option) => (option?.label ?? '').includes(input.toLowerCase())}
filterSort={(optionA, optionB) =>
(optionA?.label ?? '').toLowerCase().startsWith((optionB?.label ?? '').toLowerCase())
}
onSelect={(value) => {
dispatch(translateAction.translate(value));
}}
>
{languages.map((language) => (
<Select.Option
key={language.value}
value={language.value}
label={language.label.toLowerCase()}
disabled={language.disabled}
>
<div className="demo-option-label-item">
<span role="img" aria-label={language.label}>
{language.icon}
</span>
{language.label}
</div>
</Select.Option>
))}
</Select>
</>
);
};
export default SelectLanguage;
Теперь, когда вы нажимаете кнопку English
или French
, локализация вашего приложения соответственно изменится.
Вот и все! Вы успешно добавили поддержку локализации в свое приложение React с помощью Redux и Ant Design без использования react-i18next
. Теперь вы можете расширить эту возможность, добавив при необходимости больше языков и переводов.
Я надеюсь, что эта статья поможет вам достичь вашей цели. Дайте мне знать, если вам понадобится дополнительная помощь!