Integrates with i18next and react-i18next to enable internationalization of enum labels in React applications, with automatic UI updates after language switching.
@enum-plus/plugin-react is a plugin for enum-plus that can be considered an advanced version of @enum-plus/plugin-i18next. It provides integration with i18next and react-i18next. The plugin allows you to use i18next localization keys in enum definitions and dynamically display the translated text for the current language, making it easier and more efficient to use i18next in React applications. It automatically updates the UI after switching languages without need of refreshing the page.
It differs from the @enum-plus/plugin-i18next plugin in the following ways:
- Suitable for any JavaScript project, returning labels as string types, making it suitable for use in various mainstream frameworks.
- Can be used directly for text search and other scenarios, such as using the
Array.includesmethod to check if a label contains a certain substring, or binding to UI components like Select, where the search function works as expected. - Does not listen for language changes; when the language changes, you need to manually re-render components.
- Designed specifically for React applications, returning labels as React components that can be used directly in JSX.
- Listens for language changes; when the language changes, components automatically re-render without needing to refresh the page or manual intervention.
- Since the return value is not a string type, it cannot be directly used for text search and other scenarios. For example, the
Array.includesmethod cannot be used to check if a label contains a certain substring, or when bound to UI components like Select, the search function may fail. To solve this problem, it is recommended to use the isMatch or isMatchCaseSensitive method.
npm install @enum-plus/plugin-reactImport the @enum-plus/plugin-react plugin and install it in the entry file of your application:
- If you are using
i18next:
import { i18nextPlugin } from '@enum-plus/plugin-react';
import { Enum } from 'enum-plus';
Enum.install(i18nextPlugin);- If you are using
react-i18next:
import { reactI18nextPlugin } from '@enum-plus/plugin-react';
import { Enum } from 'enum-plus';
Enum.install(reactI18nextPlugin);When installing the plugin, you can pass a configuration object to set global options for the plugin:
- i18nextPlugin
Enum.install(i18nextPlugin, {
localize: {
// Set the i18next instance, defaults to the global i18next instance if necessary
instance: i18next,
// Options to pass to the i18next.t method
tOptions: {
// Set the namespace
ns: 'my-namespace',
// Set the default value for the return value
defaultValue: '-',
// Other options supported by the i18next.t method
// Please refer to https://www.i18next.com/translation-function/essentials#overview-options
},
defaultSearchField: 'label', // Set the field used for searching in isMatch and isMatchCaseSensitive methods, defaults to 'label'
},
});- reactI18nextPlugin
Enum.install(reactI18nextPlugin, {
localize: {
// Set the useTranslation hook, defaults to the global useTranslation hook if necessary
useTranslation: useTranslation,
// Options to pass to the useTranslation hook
useTranslationOptions: {
// Set the namespace
ns: 'my-namespace',
// Other options supported by the useTranslation hook
// Please refer to https://react.i18next.com/latest/usetranslation-hook#usetranslation-params
},
// Options to pass to the i18next.t method
tOptions: {
// Set the default value for the return value
defaultValue: '-',
// Other options supported by the i18next.t method
// Please refer to https://www.i18next.com/translation-function/essentials#overview-options
},
},
});tOptions also supports a function form to dynamically generate options, and can even directly return the final translated text.
// Use function form to dynamically generate tOptions
Enum.install(i18nextPlugin, {
localize: {
tOptions: (key) => {
if (key === 'week.sunday') {
return { ns: 'my-namespace' };
}
return { ns: 'translation' }; // Default namespace
},
},
});You can even return a string directly in tOptions as the final translated text to have full control over the behavior of the localize method.
Enum.install(i18nextPlugin, {
localize: {
tOptions: (key) => {
if (key === 'week.sunday') {
return '周日'; // Directly return the translated text
}
return instance.t(key); // Return the default translation in other cases
},
},
});You can achieve internationalization of enum labels by using localization keys in the enum definition.
import { Enum } from 'enum-plus';
const WeekEnum = Enum(
{
Monday: { value: 1, label: 'week.monday' },
Tuesday: { value: 2, label: 'week.tuesday' },
},
{
name: 'weekDays.name', // Optional enum type name
}
);
WeekEnum.label(1); // Monday - ReactElement
WeekEnum.name; // Week - ReactElement
i18next.changeLanguage('zh-CN');
WeekEnum.label(1); // 星期一 - ReactElement
WeekEnum.name; // 周 - ReactElementFor the UI components generated from the enum, the labels will automatically update when the language changes:
import { Button, Select } from 'antd';
import { changeLanguage } from 'i18next';
<Select options={WeekEnum.items} defaultValue={WeekEnum.Monday} />;
// Selected and displayed: Monday
<Button onClick={() => changeLanguage('zh-CN')}>Switch Language</Button>;
// After switching languages, the selected item's text will automatically update to: 星期一Since the label of the enum has become a component instance rather than a string type, it cannot be directly used for text search. You can use the isMatch or isMatchCaseSensitive method to filter enum items.
import { Select } from 'antd';
<Select options={WeekEnum.items} filterOption={WeekEnum.isMatch} />;[F] isMatch(searchText: string, item: EnumItem): boolean
The isMatch method is used to filter enum items based on search text, supporting fuzzy matching of the label of enum items, and ignoring case sensitivity.
This method is only applicable when
Enum.localizereturns a non-string value. For example, in the React framework,Enum.localizereturns a component to enable real-time UI updates when switching languages. In this case, string matching of thelabelof enum items is not possible, and you can consider using this method to filter enum items.
- Dropdown search
import { Select } from 'antd';
<Select options={WeekEnum.items} filterOption={WeekEnum.isMatch} />;- Regular filtering method
WeekEnum.items.filter((item) => WeekEnum.isMatch('Mon', item)); // Filters enum items whose label contains 'Mon'[F] isMatchCaseSensitive(searchText: string, item: EnumItem): boolean
The isMatchCaseSensitive method is similar to isMatch, but it performs case-sensitive matching.
This method is only applicable when
Enum.localizereturns a non-string value. For example, in the React framework,Enum.localizereturns a component to enable real-time UI updates when switching languages. In this case, string matching of thelabelof enum items is not possible, and you can consider using this method to filter enum items.
- Dropdown search
import { Select } from 'antd';
<Select options={WeekEnum.items} filterOption={WeekEnum.isMatchCaseSensitive} />;- Regular filtering
WeekEnum.items.filter((item) => WeekEnum.isMatch('mon', item)); // Filters enum items whose label contains 'mon' (case-sensitive)