I am not sure why the return statements within App.js gets called 3 times during page refreshes.
My Index.js:
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import "assets/plugins/nucleo/css/nucleo.css";
import "@fortawesome/fontawesome-free/css/all.min.css";
import "assets/scss/argon-dashboard-react.scss";
import { Auth0ProviderWithNavigate } from "./auth0-provider-with-navigate";
import { App } from "./app";
import store from "./app/store";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<BrowserRouter>
<Auth0ProviderWithNavigate>
<Provider store={store}>
{console.log("Hit from Index")}
<App />
</Provider>
</Auth0ProviderWithNavigate>
</BrowserRouter>
);
My App.js
import { useAuth0 } from "@auth0/auth0-react";
import React, { useEffect } from "react";
import { Route, Routes } from "react-router-dom";
import { AuthenticationGuard } from "./components/authentication-guard";
import Admin from "layouts/Admin.js";
import Auth from "layouts/Auth.js";
export const App = () => {
const { isLoading } = useAuth0();
useEffect(() => {
console.log("Hit from App UseEffect");
}, []);
return (
<>
{console.log("Hit from App Return", isLoading)}{" "}
{isLoading ? (
<div className="page-layout">
<Auth />
</div>
) : (
<Routes>
<Route path="/" element={<Auth />} exact />
<Route path="/auth/*" element={<Auth />} />
<Route
path="/admin/*"
element={<AuthenticationGuard component={Admin} />}
/>
</Routes>
)}
</>
);
};
When I first load the page via login the return statements within App.js gets called 2 times (expected) however if I were to refresh the page it gets called 3 times whereas I expected 2.
You appear to have some confusion about what your logs mean. You are console logging as an unintentional side-effect in the App
component's return statement, so any "expected behavior" should be thrown out the window. React can "render" your component, e.g. call the function, as many times as it needs to in order to compute what needs to be committed to the DOM.
Always use the useEffect
hook to log data so you have a one-to-one relation between render (to the DOM) and an effect.
export const App = () => {
const { isLoading } = useAuth0();
useEffect(() => {
console.log("Mounting App useEffect");
}, []); // <-- run once when component mounted/initial render
useEffect(() => {
console.log("Render App to the DOM useEffect");
}); // <-- no dependency, run once each render
useEffect(() => {
console.log("useEffect because isLoading updated", isLoading);
}, [isLoading]); // <-- run only when isLoading updates
return (
<>
{isLoading ? (
<div className="page-layout">
<Auth />
</div>
) : (
<Routes>
<Route path="/" element={<Auth />} exact />
<Route path="/auth/*" element={<Auth />} />
<Route
path="/admin/*"
element={<AuthenticationGuard component={Admin} />}
/>
</Routes>
)}
</>
);
};