Javascript 在React中关闭链接点击下拉列表的最佳做法是什么?
我有以下代码:Javascript 在React中关闭链接点击下拉列表的最佳做法是什么?,javascript,reactjs,dropdown,dom-events,Javascript,Reactjs,Dropdown,Dom Events,我有以下代码: import React,{useState}来自“React”; 从“react dom”导入react dom; 从“react router dom”导入{BrowserRouter,Route,Switch,Link}; 导入“/styles.css”; 函数下拉列表({close}){ 返回( 第1页 第2页 单击我时不要隐藏下拉列表 ); } 函数头(){ 常量[isOpen,setIsOpen]=useState(false); 返回( setIsO
import React,{useState}来自“React”;
从“react dom”导入react dom;
从“react router dom”导入{BrowserRouter,Route,Switch,Link};
导入“/styles.css”;
函数下拉列表({close}){
返回(
-
第1页
-
第2页
-
单击我时不要隐藏下拉列表
);
}
函数头(){
常量[isOpen,setIsOpen]=useState(false);
返回(
setIsOpen(prev=>!prev)}>切换下拉列表
{isOpen&&setIsOpen(false)}/>
);
}
函数Page1(){
返回第1页;
}
函数第2页(){
返回第2页;
}
函数App(){
返回(
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);
如何实现这一点而不总是向下拉列表中的每个链接传递close
回调
我试图用一个钩子来实现这一点,钩子监听mousedown
并检查它是否在下拉列表中,然后单击类型a,但问题是,它在react重定向到路由之前关闭下拉列表
我已经用useClickAway钩子覆盖了ClickOutside,但我也需要useClickInsideOnLink钩子 您可以在
下拉列表中创建一个内部组件,默认情况下使用关闭
功能,还可以通过rest参数传递其他道具。大概是这样的:
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 }) {
const MyLink = ({...rest}) => {
return (
<Link {...rest} onClick={close}>
Page 1
</Link>
)
}
return (
<ul>
<li>
<MyLink to="/">
Page 1
</MyLink>
</li>
<li>
<MyLink to="/page2">
Page 2
</MyLink>
</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);
import React,{useState}来自“React”;
从“react dom”导入react dom;
从“react router dom”导入{BrowserRouter,Route,Switch,Link};
导入“/styles.css”;
函数下拉列表({close}){
常量MyLink=({…rest})=>{
返回(
第1页
)
}
返回(
-
第1页
-
第2页
-
单击我时不要隐藏下拉列表
);
}
函数头(){
常量[isOpen,setIsOpen]=useState(false);
返回(
setIsOpen(prev=>!prev)}>切换下拉列表
{isOpen&&setIsOpen(false)}/>
);
}
函数Page1(){
返回第1页;
}
函数第2页(){
返回第2页;
}
函数App(){
返回(
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);
您可以在下拉列表中创建一个内部组件,默认情况下使用关闭
功能,还可以通过rest参数传递其他道具。大概是这样的:
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 }) {
const MyLink = ({...rest}) => {
return (
<Link {...rest} onClick={close}>
Page 1
</Link>
)
}
return (
<ul>
<li>
<MyLink to="/">
Page 1
</MyLink>
</li>
<li>
<MyLink to="/page2">
Page 2
</MyLink>
</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);
import React,{useState}来自“React”;
从“react dom”导入react dom;
从“react router dom”导入{BrowserRouter,Route,Switch,Link};
导入“/styles.css”;
函数下拉列表({close}){
常量MyLink=({…rest})=>{
返回(
第1页
)
}
返回(
-
第1页
-
第2页
-
单击我时不要隐藏下拉列表
);
}
函数头(){
常量[isOpen,setIsOpen]=useState(false);
返回(
setIsOpen(prev=>!prev)}>切换下拉列表
{isOpen&&setIsOpen(false)}/>
);
}
函数Page1(){
返回第1页;
}
函数第2页(){
返回第2页;
}
函数App(){
返回(
);
}
const rootElement=document.getElementById(“根”);
render(,rootElement);
我认为您(至少)有两种选择:
- 将页眉移动到页面中(由于呈现了新页面,页眉将重新初始化)。分叉你的代码沙盒
- 让下拉菜单自己处理它的状态,并在下拉菜单中包含切换按钮。参见代码沙盒
另一种可能的方法(我不推荐它,因为它会给一个简单的问题增加不必要的复杂性)(由提问者的评论添加):
- 实际上,当道具改变或状态改变时,组件会更新
变化。引用react docs:如果您想在
一个道具改变< /强>,考虑使一个组件<强> < /强>
或者用钥匙代替。完全不受控制将是不可能的
那么选择2
要触发道具的更改,可以连接标题。
这样,当位置(和
其他路由道具)更改。基于此,可以对等参线应用更新
通过
并将以前的location.pathname与当前的location.pathname进行比较,如果路径名发生更改,则将isOpen设置回false。
事实上,我不建议这样做。但你看:
我认为您(至少)有两种选择:
- 将页眉移动到页面中(由于呈现了新页面,页眉将重新初始化)。分叉你的代码沙盒
- 让下拉菜单自己处理它的状态,并在下拉菜单中包含切换按钮。参见代码沙盒
另一种可能的方法(我不推荐它,因为它会给一个简单的问题增加不必要的复杂性)(由提问者的评论添加):
- 实际上,当道具改变或状态改变时,组件会更新
变化。引用react docs:如果您想在
一个道具改变< /强>,考虑使一个组件<强> < /强>
或者用钥匙代替。完全不受控制将是不可能的
那么选择2
要触发道具的更改,可以连接标题。
这样,当loca发生时,会通知标头组件
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch, Link, useLocation } from "react-router-dom";
import "./styles.css";
function DropDown({ close }) {
const MyLink = ({...rest}) => {
return (
<Link {...rest}>
Page 1
</Link>
)
}
return (
<ul>
<li>
<MyLink to="/">
Page 1
</MyLink>
</li>
<li>
<MyLink to="/page2">
Page 2
</MyLink>
</li>
<li>
<p>Dont hide dropdown when clicking me!</p>
</li>
</ul>
);
}
function Header() {
const [isOpen, setIsOpen] = useState(false);
const { pathname } = useLocation();
useEffect(() =>{
setIsOpen(false);
}, [pathname])
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);