React Router Route正在从未安装的功能组件创建一个null ref



有React Router经验的人可能会回答这个问题。我有一个带有登录页的应用程序,该登录页上有一个下拉菜单;注册";按钮,<Link>的到一个简单的页面与登录表单。

下拉菜单使用react ref系统在下拉菜单上放置一个ref。有一个点击事件监听器引用这个引用,这样当点击引用中的任何内容时,下拉列表的状态就不会被切换。还有一个用于单击事件侦听器的清除功能,这样当菜单关闭时,事件侦听器就不存在了。

发生的情况是,如果下拉菜单open,并且您单击登录页面的<Link>,它将从单击事件侦听器在下拉菜单上创建一个空引用,尽管我正试图完全卸载这些组件并使用react router装载另一个组件。

我不清楚我是否应该将这个LandingMenu组件转换为类组件,以便使用componentDidUnmount来触发清理功能,或者我是否错误地使用了react路由器,或者是否存在另一个"类";正确的";解决这个我不知道的问题的方法。这是代码。

应用程序.js

import React, { Component } from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import "../styles/index.css";
import Landing from "./landing/Landing";
import Login from "./login/Login";
class App extends Component {
render() {
return (
<div>
<BrowserRouter>
<Switch>
<Route path="/" exact component={Landing} />
<Route path="/login" exact component={Login} />
</Switch>
</BrowserRouter>
</div>
);
}
}
export default App;

登录按钮

import React from "react";
import { Link } from "react-router-dom";
import Button from "../common/Button";
import ChevronRight from "../icons/ChevronRight";
const LandingAuthentication = () => {
return (
<div className="login-buttons-wrapper">
<Link to="/login">
<Button Text="Sign in" Style="button-primary" Icon={<ChevronRight />} />
</Link>
</div>
);
};
export default LandingAuthentication;

登录菜单

import React, { useState, useEffect, useRef } from "react";
import "../../styles/landing-menu.css";
const LandingMenu = ({ Title, Icon, children }) => {
// visibility toggle, default closed
const [open, setOpen] = useState(false);
// set menu ref to prevent double click event
const menuRef = useRef();
// close menu if clicked anywhere outside of menu
// on initial render, add click event listener
useEffect(() => {
const onBodyClick = (event) => {
// check if element clicked is inside of menu
// if so no action is required from this event listener so exit
if (menuRef.current.contains(event.target)) {
return;
}
// else close the menu
setOpen(false);
};
// add event listener and cleanup only if menu is open
if (open === true) {
document.body.addEventListener("click", onBodyClick);
// CLEANUP
// remove event listener
return () => {
document.body.removeEventListener("click", onBodyClick);
};
}
}, [open]);
// on click toggle state
return (
<nav className="landing-menu" ref={menuRef}>
<div
className="landing-menu-title-wrapper"
onClick={() => {
setOpen(!open);
}}
>
<h3 className="landing-menu-title">{Title}</h3>
<div className="landing-menu-title-icon">{Icon}</div>
</div>
<ul className={`dropdown ${open ? "visible" : "hidden"}`}>{children}</ul>
</nav>
);
};
export default LandingMenu;

该错误最终是由React处理React 17中引用的方式更新引起的。解决方案是从以下内容更新if语句:

if (menuRef.current.contains(event.target)) {

if (menuRef.current && menuRef.current.contains(event.target)) {

最新更新