Atomico — это современная библиотека для создания веб-компонентов на JavaScript с реактивным подходом. Одной из ключевых задач при разработке интернационализированных приложений является динамическая локализация — возможность менять язык интерфейса на лету, без перезагрузки страницы. Atomico предоставляет удобные инструменты для реализации таких сценариев с минимальными накладными расходами.
В Atomico реактивность строится вокруг функции useState.
Она позволяет компоненту автоматически обновляться при изменении
состояния. Для динамической локализации важно хранить текущий язык и
словарь фраз в реактивном состоянии:
import { component, useState } from "atomico";
const i18nData = {
en: { greeting: "Hello", farewell: "Goodbye" },
ru: { greeting: "Привет", farewell: "До свидания" },
};
export const MyComponent = component(() => {
const [lang, setLang] = useState("en");
const t = key => i18nData[lang][key] || key;
return (
<host>
<p>{t("greeting")}</p>
<button oncl ick={() => setLang(lang === "en" ? "ru" : "en")}>
Switch Language
</button>
</host>
);
});
Ключевые моменты:
useState создаёт реактивное состояние
lang.t(key) работает как простой переводчик.lang автоматически перерисует
компонент.Для масштабных приложений удобно вынести локализацию в отдельный
контекст. Atomico поддерживает createContext и
useContext, что позволяет передавать данные языковых
настроек глубоко по дереву компонентов без проп-дриллинга.
import { createContext, useContext } from "atomico";
export const I18nContext = createContext({
lang: "en",
setLang: () => {},
t: key => key
});
// Провайдер
export const I18nProvider = component(({ children }) => {
const [lang, setLang] = useState("en");
const t = key => i18nData[lang][key] || key;
return (
<I18nContext.Provider value={{ lang, setLang, t }}>
{children}
</I18nContext.Provider>
);
});
// Использование в компоненте
export const Greeting = component(() => {
const { t, setLang } = useContext(I18nContext);
return (
<host>
<p>{t("greeting")}</p>
<button oncl ick={() => setLang("ru")}>RU</button>
<button oncl ick={() => setLang("en")}>EN</button>
</host>
);
});
Преимущества такого подхода:
useContext.Для приложений с большим числом фраз может потребоваться
подгрузка словарей на лету. Atomico поддерживает
реактивные эффекты через useEffect, что позволяет
асинхронно загружать переводы при смене языка:
import { useEffect } from "atomico";
export const MyComponent = component(() => {
const [lang, setLang] = useState("en");
const [dict, setDict] = useState({});
useEffect(async () => {
const data = await fetch(`/locales/${lang}.json`).then(r => r.json());
setDict(data);
}, [lang]);
const t = key => dict[key] || key;
return (
<host>
<p>{t("greeting")}</p>
<button oncl ick={() => setLang("ru")}>RU</button>
<button oncl ick={() => setLang("en")}>EN</button>
</host>
);
});
Особенности реализации:
useEffect с зависимостью [lang] позволяет
подгружать словарь только при смене языка.setDict обновляет реактивное состояние, инициируя
перерисовку.Для крупного проекта стоит разделять словари по модульным файлам и загружать их лениво. Это снижает нагрузку на сеть и ускоряет первоначальный рендер. Atomico хорошо сочетается с динамическими импортами:
useEffect(() => {
import(`./locales/${lang}.js`).then(module => setDict(module.default));
}, [lang]);
Преимущества:
Иногда нужно не просто вставить текст, а форматировать строки с переменными. Для этого можно использовать функцию-шаблонизатор:
const format = (template, vars) =>
template.replace(/\{(\w+)\}/g, (_, key) => vars[key] || "");
const t = key => format(dict[key] || key, { name: "Alex" });
<p>{t("welcome_user")}</p> // "Добро пожаловать, Alex"
Особенности:
Atomico строит компоненты как Web Components. Это значит, что динамическая локализация работает не только внутри React-подобных компонентов, но и в любых HTML-страницах. Можно использовать атрибуты для передачи языка:
<MyComponent lang="ru"></MyComponent>
Внутри компонента можно реагировать на изменение атрибута с помощью
useProp:
const [lang] = useProp("lang");
Это позволяет интегрировать локализацию с существующими системами, не меняя архитектуру приложения.
Эти подходы обеспечивают гибкую, масштабируемую и полностью реактивную систему локализации, которая полностью использует возможности Atomico.