react-i18next多语言切换失效,无法读取翻译JSON文件
react-i18next 翻译不生效问题排查与解决
我在应用中实现react-i18next用于英法双语切换,但功能异常。{t("submit")}直接渲染为字符串"submit",没有读取翻译文件中对应的"Login"值。我怀疑是JSON翻译文件的识别问题,已经检查过路径和拼写但未解决,附上相关代码:
相关代码
index.jsx
import { createRoot } from "react-dom/client"; import { createBrowserRouter, RouterProvider, Outlet, } from "react-router-dom"; import "./i18n"; import {Suspense} from "react"; import MonitoringOverview from "./routes/MonitoringOverview"; import PerformanceQuality from "./routes/PerformanceQuality"; import Finance from "./routes/Finance"; import Navbar from "./components/Navbar/Navbar"; import "./App.css"; import LoginScreen from "./routes/LoginScreen/LoginScreen"; import UserConfig from "./routes/UserConfig/UserConfig.js"; import Simulation from "./routes/Simulation"; import Fraud from "./routes/Fraud"; const AppLayout = () => { return ( <Suspense fallback={null}> <> <Navbar /> <Outlet /> </> </Suspense> ); } const router = createBrowserRouter([ { path: '/', element: <LoginScreen /> }, { element: <AppLayout />, children: [ { path: "monitoringoverview", element: <MonitoringOverview />, }, { path: "performancequality", element: <PerformanceQuality />, }, { path: "finance", element: <Finance />, }, { path: "simulation", element: <Simulation />, }, { path: 'userconfig', element: <UserConfig /> }, { path: 'fraud', element: <Fraud /> }, ], }, ]); createRoot(document.getElementById("root")).render( <RouterProvider router={router} /> );
i18n.js
import i18n from 'i18next'; import Backend from 'i18next-http-backend'; import LanguageDetector from 'i18next-browser-languagedetector' import { initReactI18next } from 'react-i18next'; i18n.use(Backend) .use(LanguageDetector) .use(initReactI18next) .init({ backend: { //translation file path loadPath: "/public/assets/i18n/{{ns}}/{{lng}}.json", }, fallbackLng: "en", //disableed in production debug: false, // can have multiple namespaces to divide translation into smaller pieces and load them on demand ns: ["login","navbar"], interpolation: { escapeValue: false, formatSeperator: ",", }, react: { wait: true, }, }) export default i18n;
LoginScreen.js
import React, {useState} from 'react' import "./LoginScreen.css" import {Navigate} from "react-router-dom"; import pangeaLogo from "./images/pangealogosmall.png" // i18n implementation import { useTranslation } from 'react-i18next'; function LoginScreen() { // React States const [errorMessages, setErrorMessages] = useState({}); const [isSubmitted, setIsSubmitted] = useState(false); const { t } = useTranslation(["login"]); //Database for demo authentication const database = [ { username: "admin", password: "pangea123", }, { username: "admin2", password: "Pangea1234$", } ]; const errors = { uname: "invalid username", pass: "invalid password", }; //Submit handling const handleSubmit = (event) => { //Prevent page reload event.preventDefault(); var { uname, pass } = document.forms[0]; // Find user login info const userData = database.find((user) => user.username === uname.value); // Compare user info if (userData) { if (userData.password !== pass.value) { // Invalid password setErrorMessages({ name: "pass", message: errors.pass }); } else { setIsSubmitted(true); } } else { // Username not found setErrorMessages({ name: "uname", message: errors.uname }); } }; //Error messages handling const renderErrorMessage = (name) => name === errorMessages.name && ( <div className="error">{errorMessages.message}</div> ); //Login Form const renderForm = ( <div className="form"> <form action="" onSubmit={handleSubmit}> <div className="input-container"> <label for="inp" class="inp"> <input type="text" id="inp" placeholder=" " name="uname" required/> <span class="label">Username</span> <span class="focus-bg"></span> </label> {renderErrorMessage("uname")} </div> <div className="input-container"> <label for="inp" class="inp"> <input id="inp" placeholder=" " type="password" name="pass" required /> <span class="label">Password</span> <span class="focus-bg"></span> </label> {renderErrorMessage("pass")} </div> <div className="button-container"> <input type="submit" value={t("submit")} /> </div> </form> </div> ); return( <div className="app"> <div className="login-form"> <img className='pangeaLogo' src={pangeaLogo} alt="pangeaLogo" /> <div className="title">Welcome to Pangea Insights Application</div> <div className='project-name'>Congo DRC Operational Process</div> <div className='login-please'>Please {t("submit")}</div> {isSubmitted ? <Navigate to="/monitoringoverview" />: renderForm } </div> </div> ); } export default LoginScreen
en.js(翻译文件)
{ "submit": "Login" }
问题排查与解决
1. 修正翻译文件路径配置
React项目中public是静态资源根目录,请求路径无需包含/public,修改i18n.js中的loadPath:
loadPath: "/assets/i18n/{{ns}}/{{lng}}.json"
2. 确认文件实际存放位置
确保翻译文件路径与配置完全匹配:
- 英文翻译文件:
public/assets/i18n/login/en.json - 法文翻译文件:
public/assets/i18n/login/fr.json
3. 启用debug模式排查
将i18n.js中debug设为true,查看控制台日志,确认翻译文件是否成功加载:
debug: true,
4. 包裹LoginScreen组件到Suspense中
当前LoginScreen作为根路径组件,未被Suspense包裹,修改路由配置:
{ path: '/', element: ( <Suspense fallback={null}> <LoginScreen /> </Suspense> ) },
开启react.wait: true时,组件必须被Suspense包裹才能等待翻译加载完成,否则会直接显示key值。
内容的提问来源于stack exchange,提问作者Noam TheLoreFnatic Hadad
相关产品推荐
相关产品推荐

