So I am creating a react Application (A create-react-app) and it is a multiple pages website. It has authentication, and I've used JWT Authentication in the backend. Now, I am conditionally giving the routes. I've used AuthProvider and useContext to check for authentication. The code from app.js that might help understand:
{/*IMPORT STATEMENTS*/}
function App() {
const {
isAuthenticated,
type,
login,
newToken,
setType,
setRole,
setUserId,
} = useContext(authContext);
const LStoken = localStorage.getItem('token');
const LStype = localStorage.getItem('type');
const LSrole = localStorage.getItem('role');
const LSuserId = localStorage.getItem('userId');
useEffect(() => {
if (LStoken && LStype && LSuserId) {
newToken(LStoken);
setType(LStype);
setRole(LSrole);
setUserId(LSuserId);
login();
}
}, [
LStoken,
LStype,
newToken,
setType,
login,
setRole,
setUserId,
LSuserId,
LSrole,
]);
return (
<Routes>
{!isAuthenticated && (
<>
<Route path="/" element={<IndexScreen />} />
<Route path="/login" element={<LoginScreen />} />
<Route path="/register" element={<SignupScreen />} />
<Route
path="/teacherregister"
element={<TeacherSignupScreen />}
/>
<Route path="/*" element={<Navigate to={'/'} />} />
</>
)}
{isAuthenticated && type === 'student' && (
<>
<Route path="/intro" element={<IntroScreen />} />
<Route path="/session" element={<SessionScreen />} />
<Route path="/:sessionId/roles" element={<RolesScreen />} />
<Route path="/history" element={<HistoryScreen />} />
<Route
path="/:sessionId/structure"
element={<ProblemStructureScreen />}
/>
<Route
path="/:sessionId/details"
element={<DetailsScreen />}
/>
<Route
path="/:sessionId/selectproblem"
element={<SelectProblemScreen />}
/>
<Route
path="/:sessionId/test"
element={<SocketTestScreen />}
/>
<Route
path="/:sessionId/problem/"
element={<ProblemMapScreen />}
/>
<Route
path="/:sessionId/problem/notes"
element={<ScribblePadScreen />}
/>
<Route path="/*" element={<Navigate to={'/intro'} />} />
</>
)}
{isAuthenticated && type === 'teacher' && (
<>
<Route path="/intro" element={<IntroScreen />} />
<Route
path="/teacherquestions"
element={<TeacherSelectProblemScreen />}
/>
<Route path="/createquestion" element={<FormScreen />} />
<Route path="/*" element={<Navigate to={'/intro'} />} />
</>
)}
<Route path="/*" element={<Navigate to={'/'} />} />
</Routes>
);
}
export default App;
In the index.js, I am wrapping it in the following
<React.StrictMode>
<AuthProvider>
<BrowserRouter>
<App />
</BrowserRouter>
</AuthProvider>
</React.StrictMode>;
now when I'm on a conditional route, say '/:sessionId/details', and I reload the page, it automatically redirects me to the '/*' route of that block, i.e., takes me back to the '/intro' page. How do I stop that from happening??
How do I solve this?
One thing worth noting is that when the route is unconditional, it does not redirect on reload. even the login page doesn't redirect. So I reckon the authentication is causing the problem.
For reference, this is my AuthContext.js:
import React, { createContext, useState } from 'react';
const authContext = createContext({
isAuthenticated: false,
token: null,
type: 'student',
role: '',
userId: '',
newToken: () => {},
login: () => {},
logout: () => {},
setType: () => {},
setUserId: () => {},
setRole: () => {},
validSession: () => {},
});
export { authContext };
const AuthProvider = ({ children }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [token, setToken] = useState(null);
const [type, setType] = useState('student');
const [role, setRole] = useState(null);
const [userId, setUserId] = useState(null);
const [sessionId, setSessionId] = useState(null);
const login = () => {
setIsAuthenticated(true);
};
const logout = () => {
setIsAuthenticated(false);
setToken(null);
};
const newToken = (newToken) => {
setToken(newToken);
};
const validSession = (sessionId) => {
setSessionId(sessionId);
};
return (
<authContext.Provider
value={{
isAuthenticated,
token,
type,
role,
userId,
login,
logout,
newToken,
setType,
setRole,
setUserId,
}}
>
{children}
</authContext.Provider>
);
};
export default AuthProvider;
I also tried using the HashRouter instead of the BrowserRouter thinking it might solve the problem, but it didn't.