Created
December 9, 2019 16:36
-
-
Save madflanderz/cdf54c41694c16feca1b97ae9c1fd35e to your computer and use it in GitHub Desktop.
Simple i18n solution
This file contains hidden or 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