【发布时间】:2021-05-28 13:51:35
【问题描述】:
我的导航组件在这里:
import 'navigations/NavMenu.scss';
import React, { Component } from 'react';
import { Collapse, Container, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
import { Link } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
import { Util } from 'helpers/Util';
export class NavMenu extends Component {
static displayName = NavMenu.name;
constructor(props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.closeNavbar = this.closeNavbar.bind(this);
this.logout = this.logout.bind(this);
this.state = {
collapsed: true
};
}
toggleNavbar() {
this.setState({
collapsed: !this.state.collapsed
});
}
closeNavbar() {
if (!this.state.collapsed)
this.setState({ collapsed: true });
}
async logout() {
const history = useHistory();
let success = await Util.logout();
if (success) {
history.push('/login?msg=' + encodeURI('Success! You have been logged-out.') + '&type=success');
}
this.closeNavbar();
}
render() {
let theme = localStorage.getItem('theme');
let navbarClass = "navbar navbar-expand-sm navbar-toggleable-sm ng-white border-bottom box-shadow mb-3";
let login = Util.isUserLoggedIn() ?
<NavLink onClick={this.logout} tag={Link} className={theme == 'dark' ? 'text-light' : 'text-dark'} to="/login">Logout</NavLink> :
<NavLink onClick={this.closeNavbar} tag={Link} className={theme == 'dark' ? 'text-light' : 'text-dark'} to="/login">Login</NavLink>
return (
<header>
<nav className={theme == 'dark' ? navbarClass + ' navbar-dark' : navbarClass + 'navbar-light'}>
<Container>
<NavbarBrand tag={Link} to="/">NetCoreReact</NavbarBrand>
<NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
<Collapse className="d-sm-inline-flex flex-sm-row-reverse" isOpen={!this.state.collapsed} navbar>
<ul className="navbar-nav flex-grow">
<NavItem>
<NavLink onClick={this.closeNavbar} tag={Link} className={theme == 'dark' ? 'text-light' : 'text-dark'} to="/">Home</NavLink>
</NavItem>
<NavItem>
<NavLink onClick={this.closeNavbar} tag={Link} className={theme == 'dark' ? 'text-light' : 'text-dark'} to="/counter">Counter</NavLink>
</NavItem>
<NavItem>
<NavLink onClick={this.closeNavbar} tag={Link} className={theme == 'dark' ? 'text-light' : 'text-dark'} to="/fetch-data">Fetch data</NavLink>
</NavItem>
<NavItem>
{login}
</NavItem>
</ul>
</Collapse>
</Container>
</nav>
</header>
);
}
}
我想通过按注销navigation link 来logout()。但是useHistory() 把我搞砸了。这是错误:
未处理的拒绝(错误):无效的挂钩调用。钩子只能是 在函数组件的主体内部调用。这可能发生 出于以下原因之一:
- 您可能有不匹配的 React 版本和渲染器(例如 React DOM)
- 您可能违反了 Hooks 规则
- 您可能在同一个应用程序中拥有多个 React 副本,请参阅 .... 了解有关如何调试和 解决这个问题。
当这段代码被调用时:
history.push('/login?msg=' + encodeURI('Success! You have been logged-out.') + '&type=success');
如何安全导航?
【问题讨论】:
-
钩子不能在基于
Class的组件中使用,如果你想使用React Hooks,你必须将此组件更改为functional组件,或者你可以import { withRouter } from 'react-router-dom'并用@包裹NavMenu987654332@ HOC 并通过道具访问历史记录,即props.history -
在 react 路由组件中使用历史有很多问题。但是,该方法取决于您使用的反应路由器版本。对于最新版本的 react router,他们似乎只希望你使用函数组件。
标签: reactjs react-router