Why my react app reloads the homepage every time I change the language?

Viewed 55

I have two buttons on my react app's header. One for translating the application to Spanish and the other for English. The problem is that every time I press one of this buttons and update the state, the homepage gets loaded despite the translation is completed correctly. How can I avoid this redirection to the homepage and remain in the current page where the user is at that moment?

App.js, where the IntlProvider gets the language through state triggered by onclick function:

import { MsalProvider } from "@azure/msal-react";
import "bootstrap/dist/css/bootstrap.min.css";
import { IntlProvider } from "react-intl";
import { BrowserRouter } from "react-router-dom";
import "./App.css";
import AppContent from "./AppContent";
import { lang } from "./assets/lang/lang";
import Header from "./pages/common/Header";
import { useState } from "react";

function App({ msalInstance }) {
  const [localeLanguage, setLocaleLanguage] = useState("en");
  const onChangeLanguage = (lang) => {
    setLocaleLanguage(lang);
  };
  return (
    <MsalProvider instance={msalInstance}>
      <BrowserRouter>
        <IntlProvider
          key={localeLanguage}
          locale={localeLanguage}
          messages={lang[localeLanguage]}
        >
          <Header onChangeLanguage={onChangeLanguage} />
          <AppContent />
        </IntlProvider>
      </BrowserRouter>
    </MsalProvider>
  );
}
export default App;

Header.js, where the two buttons are:

    import { useIsAuthenticated, useMsal } from "@azure/msal-react";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import logo from "../../assets/img/softwareOne.png";
import { loginRequest } from "../../util/authConfig";
import { useIntl } from "react-intl";

export default function Header(props) {
  const isAuthenticated = useIsAuthenticated();
  const { instance } = useMsal();
  const intl = useIntl();

  return (
    <nav className="navbar navbar-expand-lg navbar-light bg-light">
      <Link className="navbar-brand" to="/">
        <img src={logo} className="logo-navbar" alt="" />
      </Link>
      <div className="collapse navbar-collapse text-center">
        <span className="navbar-text">
          <FormattedMessage id="well_architected_survey" />
        </span>
      </div>
      <div className="flex">
        <button
          className="btn btn-secondary"
          onClick={() => {
            props.onChangeLanguage("es");
          }}
          value="es"
        >
          {intl.locale === "es" ? "Español" : "Spanish"}
        </button>
        <button
          className="btn btn-secondary m-3"
          onClick={() => {
            props.onChangeLanguage("en");
          }}
          value="en"
        >
          {intl.locale === "en" ? "English" : "Inglés"}
        </button>
      </div>
      <div>
        <button
          className="btn btn-outline-secondary logout-header"
          onClick={() =>
            isAuthenticated
              ? instance.logoutRedirect({ postLogoutRedirectUri: "/" })
              : instance.loginRedirect(loginRequest)
          }
        >
          <FormattedMessage
            id={isAuthenticated ? "logout_button" : "login_button"}
          />
        </button>
      </div>
    </nav>
  );
}
1 Answers

I see that the localeLanguage state is used as a React key on the IntlProvider component. When the key value changes this will necessarily remount that component and its entire React subtree (which may very well include any initial mounting effects in any rendered children components). I don't see a point of using a React key here though so it's likely safe to remove it.

function App({ msalInstance }) {
  const [localeLanguage, setLocaleLanguage] = useState("en");
  const onChangeLanguage = (lang) => {
    setLocaleLanguage(lang);
  };
  return (
    <MsalProvider instance={msalInstance}>
      <BrowserRouter>
        <IntlProvider // <-- remove key prop
          locale={localeLanguage}
          messages={lang[localeLanguage]}
        >
          <Header onChangeLanguage={onChangeLanguage} />
          <AppContent />
        </IntlProvider>
      </BrowserRouter>
    </MsalProvider>
  );
}
Related