2

I have an onClick event in react-router Link like this:

<Link
  className="nav-link"
  to="/logout" 
  onClick={() => {
    console.info('header logout onclick')
    AuthenticationService.logout()
  }}
>
  Logout
</Link>

The AuthenticationService.logout looks like this:

class AuthenticationService {
    
    registerSuccessfulLogin(username, password) {
        console.info('resgister scessfull login')
        sessionStorage.setItem("username", username);
        sessionStorage.setItem("password", password);
    }
    
    logOut() {
        console.info('autenticated service  log out')
        sessionStorage.removeItem("username");
        sessionStorage.removeItem("password");
    }
    
    isUserLoggedIn() {
        console.info('is user login in')
        let user = sessionStorage.getItem("username")
        console.info('is user login in ' + user )
        if (user === null) return false
        return true
    }
}

export default new AuthenticationService()

And the logout class looks like this:

import React from 'react'
import {Component} from 'react'

class Logout extends Component  {
  render () {
    console.info('log out')
    return <div>Logout</div>
  }
}

export default Logout

When I click on the Logout item following log is written

log out

authenticated service log out and header logout onclick is not logged.

Why are the onClick event not been triggered?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
stein korsveien
  • 1,047
  • 5
  • 13
  • 35
  • 1
    The `Link` is directly moving you to the logout page, you can use an `e.preventDefault();` inside the link then the logic of logout then use a navigate, or Keep the Link as it is and check the logout loginc inside the Logout component with a componentDidMount – Woohaik Nov 23 '22 at 13:57
  • look at this answer for help https://stackoverflow.com/a/50221614/17944979 – big boy Nov 23 '22 at 14:51

1 Answers1

0

Basically what is happening is that the navigation action is effected and any javascript running afterwards is is dropped. The Link component renders an anchor <a> tag and the browser is handling first the link being clicked, then later the onClick handler by React. Since the link navigation is handled first the component unmounts and the onClick callback isn't called.

You've a couple options:

  1. Prevent the default link behavior and issue an imperative navigation from the onClick handler.

    import { Link, useNavigate } from 'react-router-dom';
    
    ...
    
    const navigate = useNavigate();
    
    ...
    
    <Link
      className="nav-link"
      to="/logout" 
      onClick={(e) => {
        e.preventDefault();
        console.info('header logout onclick');    
        AuthenticationService.logout();
        navigate("/logout");
      }}
    >
      Logout
    </Link>
    
  2. Move the logout logic to the logout page. IMHO this is the preferred method as it centralizes the logout logic. In other words, "consumers" don't need to know how to "code" the logout logic in a callback and get the linking correct.

    <Link className="nav-link" to="/logout">
      Logout
    </Link>
    

    When the Logout component mounts it calls the auth service's logout method.

    import React, { Component } from 'react';
    
    class Logout extends Component  {
      componentDidMount() {
        AuthenticationService.logout();
      }
    
      componentDidUpdate() {
        console.info('log out');
      }
    
      render () {
        return <div>Logout</div>;
      }
    }
    
    export default Logout;
    
Drew Reese
  • 165,259
  • 14
  • 153
  • 181