I just started using React. I'm building a CRUD app with it. I made some pages that can be browsed using react-router-dom
with authentication. If the user is logged in, they are able to see those pages. Otherwise, we will be redirected to the sign-in page.
Everything works fine except for refreshing pages. When I'm at any page and click "refresh" in the browser, it should reload the last page we are currently at. But instead, the app re-renders and eventually goes back to the homepage. This is not what was intended.
import React, { useEffect, useState } from "react";
import "./app.css";
import Sidebar from "./components/sidebar/Sidebar";
import Topbar from "./components/topbar/Topbar";
import Home from "./pages/Home/Home";
import {
BrowserRouter as Router,
Route,
Routes,
Navigate,
} from "react-router-dom";
import Users from "./pages/Users/Users";
import Patients from "./pages/Patients/Patients";
import PatientDetails from "./pages/PatientDetails/PatientDetails";
import AccountSettings from "./pages/AccountSettings/AccountSettings";
import SignIn from "./pages/SignIn/SignIn";
import UpdateUserForm from "./pages/UserForm/UpdateUserForm";
import CreateUserForm from "./pages/UserForm/CreateUserForm";
import CreatePatientForm from "./pages/PatientForm/CreatePatientForm";
import UpdatePatientForm from "./pages/PatientForm/UpdatePatientForm";
import CreateAppointmentForm from "./pages/AppointmentForm/CreateAppointmentForm";
import UpdateAppointmentForm from "./pages/AppointmentForm/UpdateAppointmentForm";
import axios from "axios";
import UserContext from "./utils/UserContext";
// use react-router before v.6.5.0
export default function App() {
const [user, setUser] = useState(false);
const getLoginStatus = async () => {
const data = localStorage.getItem("DENTAL_ART_LOGGED_USER");
console.log(data);
if (data) {
const res = await axios.get("http://localhost:3001/api/login/status", {
params: JSON.parse(data),
});
if (res.data) {
setUser(res.data);
}
}
};
const postUserLogin = async (userValues) => {
try {
const res = await axios.post(
"http://localhost:3001/api/signin",
userValues
);
setUser(res.data.user);
// save user to localStorage
localStorage.setItem("DENTAL_ART_LOGGED_USER", JSON.stringify(res.data));
} catch (error) {
console.log(error);
}
};
const getUserLogout = async (e) => {
// grab user session information on localStorage, passed it to server as an information to delete that session in DB.
const data = localStorage.getItem("DENTAL_ART_LOGGED_USER");
try {
const res = await axios.get("http://localhost:3001/api/signout", {
params: JSON.parse(data),
});
// reset the user state (value: false)
setUser(res.data);
localStorage.removeItem("DENTAL_ART_LOGGED_USER");
getLoginStatus();
} catch (error) {
console.log(error);
}
};
useEffect(() => {
if (!user) {
getLoginStatus();
}
}, []);
return (
<UserContext.Provider value={{ user, postUserLogin, getUserLogout }}>
<Router>
<Routes>
<Route
path="/signin"
element={user ? <Navigate to="/" /> : <SignIn />}
/>
<Route
path="*"
element={
<>
<Topbar />
<div className="container">
<Sidebar />
<Routes>
<Route
index
exact
path="/"
element={user ? <Home /> : <Navigate to="/signin" />}
/>
<Route
exact
path="/patients"
element={user ? <Patients /> : <Navigate to="/signin" />}
/>
<Route
exact
path="/users"
element={user ? <Users /> : <Navigate to="/signin" />}
/>
<Route
exact
path="/patient/:patientId"
element={
user ? <PatientDetails /> : <Navigate to="/signin" />
}
/>
;
<Route
exact
path="/patient/:patientId?/appointmentForm/create"
element={
user ? (
<CreateAppointmentForm />
) : (
<Navigate to="/signin" />
)
}
/>
<Route
exact
path="/patient/:patientId?/appointmentForm/:appointmentId?/edit"
element={
user ? (
<UpdateAppointmentForm />
) : (
<Navigate to="/signin" />
)
}
/>
<Route
exact
path="/accountSettings"
element={
user ? <AccountSettings /> : <Navigate to="/signin" />
}
/>
<Route
exact
path="/userForm/:userId?/edit"
element={
user ? <UpdateUserForm /> : <Navigate to="/signin" />
}
/>
<Route
exact
path="/userForm/create"
element={
user ? <CreateUserForm /> : <Navigate to="/signin" />
}
/>
<Route
exact
path="/patientForm/create"
element={
user ? <CreatePatientForm /> : <Navigate to="/signin" />
}
/>
<Route
exact
path="/patientForm/:patientId?/edit"
element={
user ? <UpdatePatientForm /> : <Navigate to="/signin" />
}
/>
</Routes>
</div>
</>
}
/>
</Routes>
</Router>
</UserContext.Provider>
);
}
Some resources suggested using localStorage
to save the current route/path using the useLocation
hook, so whenever the path we are currently at changes, the browser will save that path to localStorage
, and it will get it back when refreshes happen.
But I'm not sure that is the best practice, since I don't find useLocation
can be implemented inside the React App
component.