I'm implementing React localization using react-i18next & i18n, the i18next languageChanged fires, but the components in which I use the function t()
don't re-render automatically, the UI changes only when manually reloading the page.
i18n.js
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
i18n
// detect user language
.use(LanguageDetector)
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
.init({
debug: true,
fallbackLng: "en",
interpolation: {
escapeValue: false,
},
resources: {
en: {
translation: {
greeting: "Hello",
},
},
ar: {
translation: {
greeting: "مرحبا",
},
},
},
});
export default i18n;
main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./i18n";
import "./index.css";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
App.jsx
import { Suspense } from "react";
import LanguageSelector from "@/components/language/LanguageSelector";
import Home from "@/pages/root/Home";
function App() {
return (
<Suspense fallback={<p>laoding</p>}>
<LanguageSelector />
<Home />
</Suspense>
);
}
export default App;
LanguageSelector.jsx, the component that changes the language:
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
const languages = [
{ code: "en", nativeName: "English" },
{ code: "ar", nativeName: "العربية" },
];
const LanguageSelector = () => {
const { i18n } = useTranslation();
useEffect(() => {
document.body.dir = i18n.dir();
}, [i18n, i18n.language]);
return (
<div className="flex-center mt-10 gap-5">
{languages.map((lng) => (
<button
className={`${
lng.code === i18n.resolvedLanguage ? "bg-green-100" : ""
} border rounded-xl p-3`}
key={lng.code}
onClick={() => i18n.changeLanguage(lng.code)}
>
{lng.nativeName}
</button>
))}
</div>
);
};
export default LanguageSelector;
Home.jsx, the component that uses t()
and does not re-render on languageChange:
import React from "react";
import { useTranslation } from "react-i18next";
const Home = () => {
const { t } = useTranslation();
return (
<h1 className="flex-center h-full-screen text-4xl">{t("greeting")}</h1>
);
};
export default Home;
I have tried this Issue's solution and added these options to i18n.js init:
react: {
bindI18n: "loaded languageChanged",
bindI18nStore: "added",
useSuspense: true,
},
And that didn't help. What am I missing?
I got this problem too since i upgraded react-i18next from v12.3.1 to v14.0.2 yesterday. I decided to downgrade to the former version now it' fine.