-
-
Save vigosan/039ed42a5a21dfe14357cd980b0d4763 to your computer and use it in GitHub Desktop.
Simple i18n solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useCallback, useMemo } from "react" | |
import LanguageKeysDe from "./de" | |
import LanguageKeys, { LangProps } from "./en" | |
/** | |
Full example here: | |
https://codesandbox.io/s/simple-react-typescript-i18n-w0ut6 | |
**/ | |
const de = new LanguageKeysDe() | |
const en = new LanguageKeys() | |
type State = { lang: string; keys: LanguageKeys } | |
const LangStateContext = React.createContext<State | undefined>(undefined) | |
const LangUpdaterContext = React.createContext< | |
React.Dispatch<React.SetStateAction<"en" | "de">> | undefined | |
>(undefined) | |
const LangProvider: React.FunctionComponent<{}> = ({ children }) => { | |
const [lang, setLang] = React.useState<"en" | "de">("en") | |
const value = useMemo(() => { | |
return { | |
lang, | |
keys: lang === "de" ? de : en, | |
} | |
}, [lang]) | |
return ( | |
<LangStateContext.Provider value={value}> | |
<LangUpdaterContext.Provider value={setLang}> | |
{children} | |
</LangUpdaterContext.Provider> | |
</LangStateContext.Provider> | |
) | |
} | |
function useLangState() { | |
const langState = React.useContext(LangStateContext) | |
if (langState === undefined) { | |
throw new Error("useLangState must be used within a LangProvider") | |
} | |
return langState | |
} | |
function useT() { | |
const langState = useLangState() | |
const t = useCallback( | |
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |
(id: LangProps, data?: any): string => { | |
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |
const textItem: any = (langState.keys as any)[id] | |
const str: string = textItem || id | |
return textItem instanceof Function ? textItem(data) : str | |
}, | |
[langState] | |
) | |
return t | |
} | |
function useLang() { | |
const langState = useLangState() | |
return langState.lang | |
} | |
function useSetLang() { | |
const setLang = React.useContext(LangUpdaterContext) | |
if (setLang === undefined) { | |
throw new Error("useSetLang must be used within a LangProvider") | |
} | |
return setLang | |
} | |
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |
type Props = { id: LangProps; data?: any } | |
// eslint-disable-next-line react/display-name | |
const T = React.memo(({ id, data }: Props) => { | |
const t = useT() | |
return <>{t(id, data)}</> | |
}) | |
export { LangProvider, useSetLang, useT, useLang, T } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment