我有以下代码:Link to Sandbox
import React, { useState } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";
import "./styles.css";
function DropDown({ close }) {
return (
<ul>
<li>
<Link to="/" onClick={close}>
Page 1
</Link>
</li>
<li>
<Link to="/page2" onClick={close}>
Page 2
</Link>
</li>
<li>
<p>Dont hide dropdown when clicking me!</p>
</li>
</ul>
);
}
function Header() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(prev => !prev)}>Toggle DropDown</button>
{isOpen && <DropDown close={() => setIsOpen(false)} />}
</div>
);
}
function Page1() {
return <h1>Page 1</h1>;
}
function Page2() {
return <h1>Page 2</h1>;
}
function App() {
return (
<div className="App">
<BrowserRouter>
<Header />
<Switch>
<Route exact path="/" component={Page1} />
<Route path="/page2" component={Page2} />
</Switch>
</BrowserRouter>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
如何实现此功能而不总是将 close
回调传递给下拉列表中的每个链接?
我正在尝试使用一个钩子(Hook)来实现此功能,该钩子(Hook)监听 mousedown
并检查它是否在下拉列表内并单击 A 类型,但问题是它会在 react 之前关闭下拉列表重定向到路线。
外部的点击我已经用 useClickAway 钩子(Hook)覆盖了,但我还需要一个 useClickInsideOnLink 钩子(Hook)。
最佳答案
我认为你(至少)有两个选择:
- 将标题移动到页面中(由于呈现新页面,标题被重新初始化)。 fork 您的 CodeSandbox here
- 让 DropDown 自行处理其状态,并将切换按钮包含在下拉列表中。请参阅 CodeSandbox here
另一种可能的方法(我不推荐它,因为它给一个简单的问题增加了不必要的复杂性)(由提问者的评论添加):
实际上,当 props 更改或状态更改时,组件会更新 变化。引用 react 文档:如果你想“重置”某些状态 prop 发生变化,请考虑制作一个组件 fully controlled 或 fully uncontrolled 用 key 代替。完全不受控制将是 然后选择 2。
要触发 props 的更改,您可以连接 Header withRouter 。 这样,当位置(和 其他路由属性)更改。基于此,您可以将更新应用于 isOpen 通过lifecycleMethod componentDidUpdate状态 并将之前的 location.pathname 与当前的进行比较,如果路径名发生更改,则将 isOpen 设置回 false。 其实我不建议这样做。但你看: CodeSandbox
关于javascript - 在 React 中单击链接时关闭下拉菜单的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58855659/