Closed thomas-claireau closed 9 months ago
Same issue
I also encountered this issue, and my solution was to abandon this library and implement a global i18n solution using createContext myself.
import React from "react";
import { getLocales } from "expo-localization";
import * as SecureStore from "expo-secure-store";
import type { Settings } from "@/interfaces";
import en from "@/locales/en.json";
import zh from "@/locales/zh.json";
type Locale = "zh" | "en";
const fallbackLocale: Locale = "zh";
const translations: Record<Locale, Record<string, string>> = {
en,
zh,
};
export interface ILocaleContext {
t: (key: string) => string;
locale: Locale;
}
export interface ILocaleProviderProps {}
export const LocaleContext = React.createContext<ILocaleContext>({
t: (key: string) => translations[fallbackLocale][key],
locale: fallbackLocale,
});
export const LocaleProvider = (
props: React.PropsWithChildren<ILocaleProviderProps>
) => {
const { children } = props;
const settings = SecureStore.getItem("settings") || "{}";
const locale = React.useMemo<Locale>(
() =>
// First select the language based on the user's preferred setting.
(JSON.parse(settings) as Settings).locale ||
// Then consider the system's preferred language.
getLocales()[0].languageTag ||
// If both are unavailable, use the default language.
fallbackLocale,
[settings]
);
const t = React.useCallback(
(key: string) => translations[locale][key],
[locale]
);
return (
<LocaleContext.Provider
value={{
t,
locale,
}}
>
{children}
</LocaleContext.Provider>
);
};
@patlux @thomas-claireau can you please post a snippet of code reproducing the issue? Extra points if it's not a react-native project.
Just faced a similar issue, I was trying to spread i18n and that was causing issues. Then I changed t like under and now works
export const useTranslations = () => {
const [locale, setLocale] = useState(i18n.locale || 'en');
const handleLanguageChange = (newLocale: string) => {
i18n.locale = newLocale;
setLocale(newLocale); // This will trigger a re-render
};
return { handleLanguageChange, locale, t: (...args) => i18n.t(args) };
};
@zRelux When you do const t = i18n.t
, your not necessarily binding this
to the object that owns the function. Instead, you need to use const t = i18n.t.bind(i18n)
. This will ensure that t
is bound to i18n
.
That said, I don't think it's the same issue @thomas-claireau posted. Is it?
I'm closing this issue as nobody included a sample that reproduces the issue. Feel free to reopen it once a sample is available.
@fnando I ran into the same issue with the latest 4.4.3
release - here's a minimal setup to reproduce:
const i18n = new I18n({
en: {
hello: "world",
},
})
console.log(i18n.t("hello")) // this one works
const t = i18n.t
console.log(t("hello")) // this one fails
const t2 = i18n.t.bind(i18n)
console.log(t2("hello")) // this one works again
With later versions of i18n-js
, the error message actually changes to Cannot read property 'locale' of undefined
instead of get
, so it took me a moment to find this GH issue.
Maybe one of the following options would be helpful for future users:
bind
-based workaround in the README.this
value from the start, which would make destructuring risk-free.
Description
When I tried to load some translations with i18n-js, I have an error like this one :
How to reproduce
My repository is a Solito monorepo and I want to use your library to translate the React Native part.
To reproduce this error :
What do you expect
[Describe what do you expect to happen]
I would like there to be no more errors when calling the
get
methodFull backtrace