UNPKG

andrei-bread-i18n

Version:

Small and type-safe package to create multi-language interfaces.

76 lines (75 loc) 2.46 kB
import { useCallback, useContext, useEffect, useReducer, useRef, useState, } from "react"; import { I18NContext } from "./context"; function useI18NContext() { const i18n = useContext(I18NContext); if (!i18n) { throw new Error("can not `useI18NContext` outside of the `I18NProvider`"); } return i18n; } export function useI18N() { const i18n = useI18NContext(); const [{ langState, updateCount }, setLangState] = useState(() => ({ langState: i18n.getLang(), updateCount: 0, })); const usesLang = useRef(false); useEffect(() => { i18n.subscribe((lang) => { // only update the state if // the lang is used if (!usesLang.current) { return; } setLangState((state) => ({ langState: lang, updateCount: state.updateCount + 1, })); }); }, [i18n]); const get = useCallback((key, ...rest) => { usesLang.current = true; return i18n.get(key, ...rest); }, // include the `updateCount` into the deps array // so that `get` function changes it's reference whenever // the languages changes or the translations are loaded [i18n, updateCount]); const getLang = useCallback(() => { usesLang.current = true; return i18n.getLang(); }, // include the `langState` into the deps array // so that `get` function changes it's reference whenever // the languages changes [i18n, langState]); const setLang = useCallback((newLang) => i18n.setLang(newLang), [i18n]); const subscribe = useCallback((cb, options) => i18n.subscribe(cb, options), [i18n]); const reactI18N = { get lang() { usesLang.current = true; return langState; }, get, getLang, setLang, subscribe, }; return reactI18N; } export function useTranslate() { const i18n = useI18NContext(); const [updateCount, triggerUpdate] = useReducer((v) => v + 1, 0); useEffect(() => { return i18n.subscribe(() => { triggerUpdate(); }); }, []); const translate = useCallback((key, ...rest) => { return i18n.get(key, ...rest); }, // include the `updateCount` into the deps array // so that translate changes it's reference whenever the language changes [updateCount]); return translate; }