title: How do I implement a Logout functionality from a React Router Link to imports an array?
body: <p>I am trying to implement a logout functionality and am not sure what I need to do to implement it with my current set up. I was able to set up a Login functionality that pulls the correct profile data and once logged in, the Navbar + Dropdown Items are updated to display a link to logout. However, I am unsure of how I can add the logout functionality at the moment. I have been following guides but am stuck since nothing I am trying is working, once I hit a the logout link it links to /logout but fails to actually logout. The tutorial I am following claims I can do it via the frontend (I am using JWT).</p>
  <p>Navbar.jsx:</p>
  <pre><code>import React, {useState, useEffect} from 'react';
  import {Link} from 'react-router-dom'; 
  import './Navbar.css';
  import Dropdown from './Dropdown';
  import {NavItemsList} from './NavItemsList';
  import NavItems from './NavItems';
  
  function Navbar() {
      const [click, setClick] = useState(false); 
      const [button, setButton] = useState(true);
      const [dropdown, setDropdown] = useState(false);
  
      const handleClick = () =&gt; setClick(!click);
      const closeMobileMenu = () =&gt; setClick(false);
  
      const onMouseEnter = () =&gt; {
          if (window.innerWidth &lt; 960) {
              setDropdown(false);
          } else {
              setDropdown(true);
          }
      };
  
      const onMouseLeave = () =&gt; {
          if (window.innerWidth &lt; 960) {
              setDropdown(false);
          } else {
              setDropdown(false);
          }
      };
  
      return (
          &lt;&gt;
              &lt;nav className='navbar'&gt;
                  &lt;div className='navbar-container-whole'&gt;
                      &lt;div className='left-nav-container'&gt;
                          {/* Link in react-router-dom essentially replaces a tag.*/}
                          &lt;Link to='/' className='navbar-logo'&gt;
                              &lt;img src='/images/logo.png' className='hashtek-logo' alt='logo' /&gt;
                              &lt;h1 className='navbar-name'&gt;HashTek&lt;/h1&gt;
                          &lt;/Link&gt;
                      &lt;/div&gt;
                      {/* .navbar-container will create a div with that class name. */}
                      &lt;div className='center-nav-container'&gt;
                          &lt;form action='./' method='get' id='search-form'&gt;
                              &lt;div class='searchbar'&gt;
                                  &lt;input
                                      class='searchbar_input'
                                      type='search'
                                      name='search'
                                      placeholder='Search..'
                                  /&gt;
  
                                  &lt;button type='submit' class='searchbar_button'&gt;
                                      &lt;i class='material-icons'&gt;search&lt;/i&gt;
                                  &lt;/button&gt;
                              &lt;/div&gt;
                          &lt;/form&gt;
                      &lt;/div&gt;
                      &lt;div className='right-nav-container'&gt;
                          &lt;ul className={click ? 'nav-menu active' : 'nav-menu'}&gt;
                              &lt;div className='text-links'&gt;
                                  {/* This line above is for when you are on mobile, and an item is clicked, the nav menu will disappear */}
                                  {NavItemsList.slice(0, 4).map((menu, index) =&gt; {
                                      return &lt;NavItems items={menu} key={index} /&gt;;
                                  })}
                              &lt;/div&gt;
                              &lt;div className='logo-links'&gt;
                                  {NavItemsList.slice(4, 6).map((menu, index) =&gt; {
                                      return &lt;NavItems items={menu} key={index} /&gt;;
                                  })}
                              &lt;/div&gt;
                          &lt;/ul&gt;
                          &lt;div className='menu-icon' onClick={handleClick}&gt;
                              &lt;i className={click ? 'fas fa-times' : 'fas fa-bars'} /&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/nav&gt;
          &lt;/&gt;
      );
  }
  
  export default Navbar;
  </code></pre>
  <p>NavItemList.js:</p>
  <pre><code>export const NavItemsList = [{
          title: 'Products',
          path: '/products',
          cName: 'nav-links',
      },
      {
          title: 'Stats',
          path: '/stats',
          cName: 'nav-links',
      },
      {
          title: 'Contacts',
          path: '/contacts',
          cName: 'nav-links',
          subNav: [{
                  title: 'About',
                  path: '/contacts/about',
                  cName: 'dropdown-link',
                  menuName: 'contacts-menu',
              },
              {
                  title: 'How To',
                  path: '/contacts/how-to',
                  cName: 'dropdown-link',
                  menuName: 'contacts-menu',
              },
              {
                  title: 'Developers',
                  path: '/contacts/developers',
                  cName: 'dropdown-link',
                  menuName: 'contacts-menu',
              },
              {
                  title: 'Designers',
                  path: '/contacts/designers',
                  cName: 'dropdown-link',
                  menuName: 'contacts-menu',
              },
              {
                  title: 'Mentors',
                  path: '/contacts/mentors',
                  cName: 'dropdown-link',
                  menuName: 'contacts-menu',
              },
          ],
      },
      {
          title: 'Services',
          path: '/services',
          cName: 'nav-links',
          subNav: [{
                  title: 'Streaming',
                  path: '/services/streaming',
                  cName: 'dropdown-link',
                  menuName: 'services-menu',
              },
              {
                  title: 'Editing',
                  path: '/services/editing',
                  cName: 'dropdown-link',
                  menuName: 'services-menu',
              },
          ],
      },
      {
          title: Account,
          path: '/my-account',
          cName: 'nav-links',
          subNav: [{
                  title: 'Login',
                  path: '/login',
                  cName: 'dropdown-link',
                  menuName: 'account-menu',
                  authenticated: false,
              },
              {
                  title: 'Logout',
                  path: '/logout',
                  cName: 'dropdown-link',
                  menuName: 'account-menu',
                  authenticated: true,
              },
              {
                  title: 'Profile',
                  path: '/profile',
                  cName: 'dropdown-link',
                  menuName: 'account-menu',
              },
          ],
      },
      {
          title: Help,
          path: '/help',
          cName: 'nav-links',
      },
  ];
  </code></pre>
  <p>Login.jsx:</p>
  <pre><code>import React, {useState, useEffect} from 'react';
  import {useDispatch, useSelector} from 'react-redux';
  import {Link} from 'react-router-dom';
  import {Formik, Field, Form, ErrorMessage} from 'formik';
  import * as Yup from 'yup';
  import {login} from '../../slices/auth';
  import {clearMessage} from '../../slices/messages';
  const Login = (props) =&gt; {
      const [loading, setLoading] = useState(false);
      const {isLoggedIn} = useSelector((state) =&gt; state.auth);
      const {message} = useSelector((state) =&gt; state.message);
      const dispatch = useDispatch();
      useEffect(() =&gt; {
          dispatch(clearMessage());
      }, [dispatch]);
      const initialValues = {
          username: '',
          password: '',
      };
      const validationSchema = Yup.object().shape({
          username: Yup.string().required('This field is required!'),
          password: Yup.string().required('This field is required!'),
      });
      const handleLogin = (formValue) =&gt; {
          const {username, password} = formValue;
          setLoading(true);
          dispatch(login({username, password}))
              .unwrap()
              .then(() =&gt; {
                  props.history.push('/profile');
                  window.location.reload();
              })
              .catch(() =&gt; {
                  setLoading(false);
              });
      };
      if (isLoggedIn) {
          return &lt;Link to='/profile' /&gt;;
      }
      return (
          &lt;div className='login-form'&gt;
              &lt;div className='card card-container'&gt;
                  &lt;Formik
                      initialValues={initialValues}
                      validationSchema={validationSchema}
                      onSubmit={handleLogin}
                  &gt;
                      &lt;Form&gt;
                          &lt;div className='form-group'&gt;
                              &lt;label htmlFor='username'&gt;Username&lt;/label&gt;
                              &lt;Field name='username' type='text' className='form-control' /&gt;
                              &lt;ErrorMessage
                                  name='username'
                                  component='div'
                                  className='alert alert-danger'
                              /&gt;
                          &lt;/div&gt;
                          &lt;div className='form-group'&gt;
                              &lt;label htmlFor='password'&gt;Password&lt;/label&gt;
                              &lt;Field name='password' type='password' className='form-control' /&gt;
                              &lt;ErrorMessage
                                  name='password'
                                  component='div'
                                  className='alert alert-danger'
                              /&gt;
                          &lt;/div&gt;
                          &lt;div className='form-group'&gt;
                              &lt;button
                                  type='submit'
                                  className='btn btn-primary btn-block'
                                  disabled={loading}
                              &gt;
                                  {loading &amp;&amp; (
                                      &lt;span className='spinner-border spinner-border-sm'&gt;&lt;/span&gt;
                                  )}
                                  &lt;span&gt;Login&lt;/span&gt;
                              &lt;/button&gt;
                          &lt;/div&gt;
                      &lt;/Form&gt;
                  &lt;/Formik&gt;
              &lt;/div&gt;
              {message &amp;&amp; (
                  &lt;div className='form-group'&gt;
                      &lt;div className='alert alert-danger' role='alert'&gt;
                          {message}
                      &lt;/div&gt;
                  &lt;/div&gt;
              )}
          &lt;/div&gt;
      );
  };
  export default Login;
  </code></pre>
  <p>auth.service.js:</p>
  <pre><code>//Authentication Service file. This service uses Axios for HTTP requests and Local Storage for user information &amp; JWT.
  // It provides following important functions:
  
  // register(): POST {username, email, password}
  // login(): POST {username, password} &amp; save JWT to Local Storage
  // logout(): remove JWT from Local Storage
  
  import axios from 'axios';
  const API_URL = 'http://localhost:8080/api/auth/';
  const register = (username, email, password) =&gt; {
      return axios.post(API_URL + 'signup', {
          username,
          email,
          password,
      });
  };
  const login = (username, password) =&gt; {
      return axios
          .post(API_URL + 'login', {
              username,
              password,
          })
          .then((response) =&gt; {
              if (response.data.accessToken) {
                  localStorage.setItem('user', JSON.stringify(response.data));
              }
              return response.data;
          });
  };
  const logout = () =&gt; {
      localStorage.removeItem('user');
  };
  const authService = {
      register,
      login,
      logout,
  };
  export default authService;
  </code></pre>
  <p>auth.js:</p>
  <pre><code>// We’re gonna import AuthService to make asynchronous HTTP requests with trigger one or more dispatch in the result.
  
  // – register(): calls the AuthService.register(username, email, password) &amp; dispatch setMessage if successful/failed
  // – login(): calls the AuthService.login(username, password) &amp; dispatch setMessage if successful/failed
  // – logout(): calls the AuthService.logout().
  
  // setMessage is imported from message slice that we’ve created above.
  // We also need to use Redux Toolkit createAsyncThunk which provides a thunk that will take care of the action types and dispatching the right actions based on the returned promise.
  //There are 3 async Thunks to be exported:
  
  // register
  // login
  // logout
  
  import {createSlice, createAsyncThunk} from '@reduxjs/toolkit';
  import {setMessage} from './messages';
  import AuthService from '../services/auth.service';
  const user = JSON.parse(localStorage.getItem('user'));
  export const register = createAsyncThunk(
      'auth/register',
      async ({username, email, password}, thunkAPI) =&gt; {
          try {
              const response = await AuthService.register(username, email, password);
              thunkAPI.dispatch(setMessage(response.data.message));
              return response.data;
          } catch (error) {
              const message =
                  (error.response &amp;&amp;
                      error.response.data &amp;&amp;
                      error.response.data.message) ||
                  error.message ||
                  error.toString();
              thunkAPI.dispatch(setMessage(message));
              return thunkAPI.rejectWithValue();
          }
      }
  );
  export const login = createAsyncThunk(
      'auth/login',
      async ({username, password}, thunkAPI) =&gt; {
          try {
              const data = await AuthService.login(username, password);
              return {user: data};
          } catch (error) {
              const message =
                  (error.response &amp;&amp;
                      error.response.data &amp;&amp;
                      error.response.data.message) ||
                  error.message ||
                  error.toString();
              thunkAPI.dispatch(setMessage(message));
              return thunkAPI.rejectWithValue();
          }
      }
  );
  export const logout = createAsyncThunk('auth/logout', async () =&gt; {
      await AuthService.logout();
  });
  const initialState = user
      ? {isLoggedIn: true, user}
      : {isLoggedIn: false, user: null};
  const authSlice = createSlice({
      name: 'auth',
      initialState,
      extraReducers: {
          [register.fulfilled]: (state, action) =&gt; {
              state.isLoggedIn = false;
          },
          [register.rejected]: (state, action) =&gt; {
              state.isLoggedIn = false;
          },
          [login.fulfilled]: (state, action) =&gt; {
              state.isLoggedIn = true;
              state.user = action.payload.user;
          },
          [login.rejected]: (state, action) =&gt; {
              state.isLoggedIn = false;
              state.user = null;
          },
          [logout.fulfilled]: (state, action) =&gt; {
              state.isLoggedIn = false;
              state.user = null;
          },
      },
  });
  const {reducer} = authSlice;
  export default reducer;
  </code></pre>
  <p>App.js:</p>
  <pre><code>import React, {useState, useEffect, useCallback} from 'react';
  import {useDispatch, useSelector} from 'react-redux';
  import {BrowserRouter as Router, Routes, Route} from 'react-router-dom'; //Switch was replaced by Routes in react-router-dom v6
  import './App.css';
  import Navbar from './components/Navbar';
  import Footer from './components/Footer';
  import Home from './components/pages/Home';
  import Account from './components/pages/Account';
  import Login from './components/pages/Login';
  import Profile from './components/pages/Profile';
  
  import {logout} from './slices/auth';
  import EventBus from './common/EventBus';
  
  const App = () =&gt; {
      const {user: currentUser} = useSelector((state) =&gt; state.auth);
      const dispatch = useDispatch();
      const logOut = useCallback(() =&gt; {
          dispatch(logout());
      }, [dispatch]);
      useEffect(() =&gt; {
          EventBus.on('logout', () =&gt; {
              logOut();
          });
          return () =&gt; {
              EventBus.remove('logout');
          };
      }, [currentUser, logOut]);
      return (
          &lt;&gt;
              &lt;Router&gt;
                  &lt;Navbar /&gt;
                  &lt;Routes&gt;
                      &lt;Route path='/' element={&lt;Home /&gt;} /&gt;
                      &lt;Route path='/my-account' element={&lt;Account /&gt;} /&gt;
                      &lt;Route path='/login' element={&lt;Login /&gt;} /&gt;
                      {currentUser ? (
                          &lt;Route path='/logout' onClick={logOut} /&gt;
                      ) : ( //Did something wrong here I believe. Not sure if I need to include this in another file.
                          &lt;Route path='/login' element={&lt;Login /&gt;} /&gt;
                      )}
                      &lt;Route path='/profile' element={&lt;Profile /&gt;} /&gt;
                  &lt;/Routes&gt;
                  &lt;Footer /&gt;
              &lt;/Router&gt;
          &lt;/&gt;
      );
  };
  
  export default App;
  </code></pre>
  <p>I feel like I am close, just missing something or have something in the wrong place. If anyone can help me, I would deeply appreciate it. Sorry if I included too much code, just want everyone to have a good idea of whats going on. Thank you!</p>