app.js
import React from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import configureStore from "./store/configureStore";
import { startSetExpenses } from "./actions/expenses";
import 'normalize.css/normalize.css';
import './styles/styles.scss';
import AppRouter from "./routers/AppRouter";
import 'react-dates/lib/css/_datepicker.css';
import { auth } from './firebase/firebase';
import { onAuthStateChanged } from "firebase/auth";
import { useNavigate } from "react-router-dom";
const root = createRoot(document.getElementById("app"));
const navigate = useNavigate();
const store = configureStore();
const jsx = (
<Provider store={store}>
<AppRouter />
</Provider>
);
const loadingComponent = <div><p>Loading...</p></div>;
root.render(loadingComponent);
store.dispatch(startSetExpenses())
.then(() => {
root.render(jsx);
})
.catch((error) => {
console.error("Error fetching expenses:", error);
});
onAuthStateChanged(auth, (user) => {
if(user){
console.log("LoggedIN");
navigate("/dashboard");
}else{
console.log("LoggedOUT");
navigate("/");
}
})
AppRouter.js:
import React from 'react';
import LoginPage from '../components/LoginPage';
import Header from '../components/Header';
import NotFound from '../components/NotFound';
import EditExpense from '../components/EditExpense';
import AddExpense from '../components/AddExpense';
import ExpenseDashboardPage from '../components/ExpenseDashboard';
import HelpPage from '../components/HelpPage';
import { Routes, Route, BrowserRouter } from 'react-router-dom';
const AppRouter = () => (
<BrowserRouter >
<Header/>
<Routes >
<Route path="/" element={<LoginPage />} />
<Route path="/dashboard" element={<ExpenseDashboardPage />} />
<Route path="/create" element={<AddExpense />} />
<Route path="/edit/:id" element={<EditExpense />} />
<Route path="/help" element={<HelpPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
export default AppRouter;
The store.dispatch(startSetExpenses())
is to fetch the initial data from firebase. Till it gets resolved, I am rendering the loadingComponent on screen.
What I expected by using the useNavigate from react-router-dom was to navigate to the "/" path when user is not logged in, in the onAuthStateChanged, and to "/dashboard" when a user is logged in.
But it isn’t working. How do I achieve that?
2
Answers
You should debug. Is
onAuthStateChanged
ever called? Maybe it’s not running?useNavigate
is a hook, it must be used inside a component.You cannot call React hooks outside React components or custom React hooks. I suggest moving the
useNavigate
hook call and auth state change listener intoAppRouter
and hoisting theBrowserRouter
to the index file to wrapAppRouter
to provide it the routing context.Example:
App:
AppRouter: