我在react-router
Link
中有一个onClick
事件,如下所示:
<Link
className="nav-link"
to="/logout"
onClick={() => {
console.info('header logout onclick')
AuthenticationService.logout()
}}
>
Logout
</Link>
AuthenticationService。注销看起来像这样:
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()
注销类看起来像这样:
import React from 'react'
import {Component} from 'react'
class Logout extends Component {
render () {
console.info('log out')
return <div>Logout</div>
}
}
export default Logout
当我点击Logout项目时,下面的日志被写入
退出
已认证的服务注销,标题注销onclick未被记录。
为什么onClick事件没有被触发?
基本上发生的是什么是影响导航操作和任何javascript运行之后被丢弃。Link
组件呈现一个锚<a>
标记,浏览器首先处理被单击的链接,然后处理React的onClick
处理程序。因为链接导航首先被处理,组件卸载和onClick
回调不会被调用。
你有两个选项:
-
防止默认链接行为,并从
onClick
处理程序发出命令式导航。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>
-
将注销逻辑移动到注销页面。恕我直言,这是首选的方法,因为它集中了注销逻辑。换句话说,"消费者"不需要知道如何"编码"在回调中注销逻辑并获得正确的链接。
<Link className="nav-link" to="/logout"> Logout </Link>
Logout组件挂载时,它调用auth服务的
logout
方法。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;