DevGang
Авторизоваться

Добавить локализацию и перевод в приложение React с помощью redux (без i18next)

Локализация — это процесс перевода вашего приложения на разные языки. В этой статье мы узнаем, как добавить поддержку локализации в приложение React с помощью Redux и Ant Design без использования react-i18next.

GitHub Repo

Посмотрите видео на 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. Теперь вы можете расширить эту возможность, добавив при необходимости больше языков и переводов.

Я надеюсь, что эта статья поможет вам достичь вашей цели. Дайте мне знать, если вам понадобится дополнительная помощь!

Источник:

#JavaScript #NodeJS #React #Redux
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу