1

I am making a mern application with login/registration system and the dashboard and the other routes that will only be accessible when someone logs in now the problem is i was trying to write a if condition in react router dom so that all the routes inside the dashboard could be resitricted till the user logs in , and i use 'useNavigate' hook to go back to login page if user is not logged in but the application gives me error saying useNavigate() may be used only in the context of a component , but i used the same hook in my other component too where i didnt used any router and it worked fine there and so i am not able to understand what to do , also i want to know how can i put the component name inside a variable so that if i call the function i can put the component name in it and later put that varibale like this <component_name/> and it should change its value , here is my code:-

import Navbar from "./components/navbar/Navbar";
import Home from "./components/Home/Home";
import 'bootstrap/dist/css/bootstrap.min.css'
import Forgot_password from "./components/login_and_reg/Forgot_password/Forgot_password";
import Weather from "./components/Weather/Weather";
import Landing_page from './components/login_and_reg/Landing_page/Landing_page'
import {
    BrowserRouter as Router,
    Route,
    Routes,
    useNavigate
  } from "react-router-dom";
import Verification from "./components/login_and_reg/Verification/Verification";
import Protected_routes from './components/Protected_routes'
import { useSelector } from "react-redux";

function App() {
    const loggedin = useSelector(state => state.loggedin)
    const Navigate = useNavigate();
    const rememberMe = localStorage.getItem('rememberMe')

    function checkroute(Component_name){
        if (rememberMe=='true') {
            return <Component_name/> 
        } else {
            console.log(loggedin)
            if(loggedin =='loggedin'){
                return <Component_name/> 
            }
            else{
                Navigate('/')
            }
            
        }
    }
return (
    <>
            <Router>
                {/* <Navbar/> */}
                <Routes>
                    <Route path="/weather" element={checkroute(Weather)}></Route>
                    <Route exact path="/" element={<Protected_routes/>}></Route>
                    <Route path="/verify/:first_name/:email" element={<Verification/>}></Route>
                    <Route path="/forgot_password" element={<Forgot_password/>}></Route>
                    {/* <Route exact path="/home" element={<Protected_routes/>}></Route> */}


                </Routes>
            </Router>
                
            
            
        
    </>
);
}

I also made a protected route only for login purpose but i dont know how to use it for all the components if it is possible then here is code of that component:-

import React, { Component } from 'react';
import { useSelector } from 'react-redux';
import {Navigate, Route , useNavigate} from 'react-router-dom';
import Home from './Home/Home';
import Landing_page from './login_and_reg/Landing_page/Landing_page';


const Protected_routes = () => {
    const loggedin = useSelector(state => state.loggedin)
    const Navigate = useNavigate();
    const rememberMe = localStorage.getItem('rememberMe')
    if (rememberMe=='true') {
        return <Home/> 
    } else {
        if(loggedin=='loggedin'){
            return <Home/> 
        }
        else{
            return <Landing_page/> 
        }
        
    }
    
}

export default Protected_routes

export default App;
Samyak jain
  • 137
  • 1
  • 7

1 Answers1

2

What you'd likely use a PrivateRoute component to wrap your secured pages. It will render the desired page if not logged in, or redirect to the login page.

Here's the flow:

1. Define a private route component:

// PrivateRoute.ts

import { Navigate } from 'react-router-dom';
import { useSelector } from 'react-redux';
import  React from 'react';


export function PrivateRoute({ children }: { children: React.ReactElement }) {

// the user verification logic is up to your application
// this is an example based on your code above 
    const loggedin = useSelector(state => state.loggedin);
    const rememberMe = localStorage.getItem('rememberMe');

   if (rememberMe==='true') {
    return <Navigate to={'/home'} />;
    }
  else if (loggedin==='loggedin'){
// render the wrapped page
    return children;
}
  else {
// user not logged in, redirect to the Login page which is unprotected
    return <Navigate to={'/login'} />;
  }
}

2. And use it in your router :

I assume you want to protect your Home and Wheater pages here. You can customize it to your own logic.


import React from 'react';
import { Navigate, Route, Routes } from 'react-router-dom';
import { PrivateRoute } from './PrivateRoute';
import { Home } from "./my-home-page";
import { Wheater } from "my-wheater-page";
import { Login } from "my-login-page";

export const AppRoutes = () => {
  return (
    <Routes>
        <Route
          path='home'
          element={
            <PrivateRoute>
                <Home/>
            </PrivateRoute>
          }
        />
        <Route
          path='login'
          element={
              <Login/>
          }
        />
        <Route
          path='wheater'
          element={
            <PrivateRoute>
                <Wheater />
            </PrivateRoute>
          }
        />
    </Routes>
  );
};

exaucae
  • 2,071
  • 1
  • 14
  • 24
  • Thanks a lot for this answer @exaucae but i dont really understand the 'children' part can you attach any link where i can read about it? Are those props? – Samyak jain Jan 30 '22 at 13:18
  • @Samyakjain, yes. `children` is a particular prop that contains the component wrapped inside the PrivateRoute. For instance, in our `AppRoutes`, `Wheater` component is wrapped inside `PrivateRoute` markups, that means the children prop will contain the same wheater component. Doing so, if the user is already logged in, we return that children prop to be accessible. To further expand on this, you can [read the dedicated section in React docs](https://reactjs.org/docs/composition-vs-inheritance.html) and/or [this related stackoverflow question](https://stackoverflow.com/a/49706920/13781069). – exaucae Jan 30 '22 at 16:13
  • Ohh thanks a lot , thats a great topic that you told me it helped me a lot – Samyak jain Jan 31 '22 at 06:03