DEV Community

Ricardo Uy
Ricardo Uy

Posted on • Updated on

React Router Redirect

We always encounter websites where we have to log in to be able to access some of the information that we want to know.
As a good example, We have companies like Amazon, where we needed an account to log in as a buyer to buy some products, then another account to log in as an employee, so that we can access some info about our benefits, to punch in our timecard, salary etc, or another account to log in as an administrator to acess the informations about the inventories of products or status of some employees.

If we can put them all in one website, We have to make sure that only the people we want should have access to different part of that website and that logged in user can only access the routes or pages that they are allowed to. 
Enter… React, Router ,Redirect, Switch
These groupies can simplify and solve this seemingly complex problem.

Suppose we have the following four components which is imported by the component App:

import EmployeeEdit from './components/Administrator/EmployeeEdit';
import EmployeePage from './components/Administrator/EmployeePage';

import TimeElapsed from './components/Employee/TimeElapsed';
import TimeList from './components/Employee/TimeList';

...other imports..
import { Route, Switch } from "react-router-dom";
import Header from './components/Header/Header';

function App() {

  return (
    <div>
    <NavBar />
      <Switch>
       <Route exact path="/TimeElapsed">
          <TimeElapsed />
        </Route>
        <Route exact path="/TimeList">
          <TimeList />
        </Route>

       <Route exact path="/EmployeePage">
         <EmployeePage />}
      </Route>
      <Route path="/EmployeeEdit">
        <EmployeeEdit />}
      </Route>
        <Route exact path="/">
          <Header />
        </Route>
      </Switch>
    </div>
  )
}

export default App;

Enter fullscreen mode Exit fullscreen mode

So right now, anyone can have access to all these four components.
But actually, we want only the employees to have access to the TimeElapsed and TimeList components. We do not want them to have access to the EmployeePage and EmployeeEdit components.

On the other hand, we want only the Administrator to have access to the EmployeePage and EmployeeEdit components and we dont want them access to TimeElapsed and TimeList components.
To implement that we have to have to add a login component for the employees and another login component for the administrator. This is what that component might look like:
For AdminLogin(This is just a simplified authentication example, in real life a backend is needed), this how it may be done

Function AdminLogin({ isLoggedIn, setLoggedIn })  {

      const [formData, setFormData] = useState({
        name: '',
        password: '',
      });

      const [employeeData, setEmployeeData] = useState(null);
      const [loginError, setLoginError] = useState('');

      const handleInputChange = (e) => {
        const { name, value } = e.target;
        setFormData({ ...formData, [name]: value });
      };

      const handleFormSubmit = (e) => {
        e.preventDefault();
   //  employee authentication 
        const { name, password } = formData;

         for (let i=0; i<admin.length; i++){
        if (name === admin[i].name && password === admin[i].password) {
          // If authentication is successful, fetch employee data
          setLoggedIn(true);
          } else {
            setEmployeeData(null);
      setLoginError('Invalid name or password');
          }
    };
      }
return (
      <div>
        <h3>Administrator Login</h3>
        <form onSubmit={handleFormSubmit}>
        <div>
          <label>Name:</label>
          <input
            type="text"
            name="name"
            value={formData.name}
            onChange={handleInputChange}
          />
        </div>
        <div>
          <label>Password:</label>
          <input
            type="password"
            name="password"
            value={formData.password}
            onChange={handleInputChange}
          />
        </div>
        <button type="submit">Login</button>
      </form>
           </div>
    );
  };
  export default AdminLogin
Enter fullscreen mode Exit fullscreen mode

And now we have to make some changes to the App function above:

We have to add useState hook to App, since AdminLogin is a child of App, this boolean and set function we put as props to the login function component above, and so

function App() {
  const [isLoggedIn, setLoggedIn] = useState(false);
  return (
    <div>
    <NavBar />
      <Switch>
      {/* Pretend that this is not yet coded...
        <Route exact path="/EmployeeLogin">
          <EmployeeLogin />
        </Route>*/}
        <Route exact path="/TimeElapsed">
          <TimeElapsed />
        </Route>
        <Route exact path="/TimeList">
          <TimeList />
        </Route>

 <Route path="/AdminLogin">
        <AdminLogin isLoggedIn={isLoggedIn} setLoggedIn={setLoggedIn} />
      </Route>
      <Route path="/EmployeePage">
        {isLoggedIn ? <EmployeePage /> : <Redirect to="/AdminLogin" />}
      </Route>
      <Route path="/EmployeeEdit">
        {isLoggedIn ? <EmployeeEdit /> : <Redirect to="/AdminLogin" />}
      </Route>
        <Route exact path="/">
          <Header />
        </Route>
      </Switch>
    </div>
  )
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Take note of the changes we make in the App component.
First we added Redirect to the import like so:

import { Route, Switch, Redirect } from "react-router-dom";
then, We added the AdminLogin component in App component and then make an if/else statement to both the EmployeePage and EmployeeEdit page, such that if logged in, you will be directed to the page, if not, you will be turn back to the log in page again.

We could do the same for the EmployeeLogin component.
We will make an Employee log in function:

Image description

and the final code for App component would be:

function App() {
  const [isLoggedIn, setLoggedIn] = useState(false);
const [isLoggedInEmployee, setLoggedInEmployee] = useState(false);

  return (
    <div>
    <NavBar />
      <Switch>
      <Route  path="/EmployeeLogin">
          <EmployeeLogin isLoggedInEmployee={isLoggedInEmployee} setLoggedInEmployee={setLoggedInEmployee}/>
        </Route>
        <Route  path="/TimeElapsed">
        {isLoggedInEmployee ?   <TimeElapsed /> : <Redirect to="/EmployeeLogin" />}
        </Route>
        <Route  path="/TimeList">
        {isLoggedInEmployee ?  <TimeList /> : <Redirect to="/EmployeeLogin" />}
        </Route>

 <Route path="/AdminLogin">
        <AdminLogin isLoggedIn={isLoggedIn} setLoggedIn={setLoggedIn} />
      </Route>
      <Route path="/EmployeePage">
        {isLoggedIn ? <EmployeePage /> : <Redirect to="/AdminLogin" />}
      </Route>
      <Route path="/EmployeeEdit">
        {isLoggedIn ? <EmployeeEdit /> : <Redirect to="/AdminLogin" />}
      </Route>
        <Route exact path="/">
          <Header />
        </Route>
        </Switch>
    </div>
  )}

export default App;
Enter fullscreen mode Exit fullscreen mode

Take note that for the Administrator Log in,
it is : isLoggedIn and setLoggedIn,
while for the Employee Log in it is : isLoggedInEmployee and setLoggedInEmployee. Just to differentiate them.

Now if an employee attempted to peek inside the profile page of another employee he will not be able to do so. And if he, the employee ask the Administrator her password, we will presume she will growl at him because it is supposed to be a secret.

Top comments (0)