Cri*_*alu 23 javascript reactjs
在 React 中构建自定义下拉菜单,并在单击外部尝试关闭它时遇到问题。
所以我创建了通用的 HOC,这样我也可以将它用于其他场合。
我似乎遇到的问题是我不知道如何将其ref从临时传递到组件。
我一直在研究forwardRef和其他语气的示例,但我无法弄清楚。
知道是否可能以及我该怎么做?
import React, { useState, useRef, useEffect } from "react";
export default function withClickOutside(WrappedComponent) {
const Component = (props) => {
const [open, setOpen] = useState(false);
const ref = useRef();
useEffect(() => {
const handleClickOutside = (event) => {
if (!ref?.current?.contains(event.target)) {
setOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
}, [ref]);
return <WrappedComponent {...props} open={open} setOpen={setOpen} ref={ref}/>;
};
return Component;
}
Run Code Online (Sandbox Code Playgroud)
Ama*_*pta 30
使用 React Hook 在该元素外部单击时,只需遵循 5 个步骤即可关闭菜单/更改任何元素的状态
第 1 步:导入 useRef 并定义变量
import {useRef} from "react"
const catMenu = useRef(null)
Run Code Online (Sandbox Code Playgroud)
第2步:使用React Hook进行状态改变(useState)
const [openSlide, setopenSlide] = useState("");
Run Code Online (Sandbox Code Playgroud)
第 3 步:定义一个 javascript 函数来设置状态
const closeOpenMenus = (e)=>{
if(openSlide && !catMenu.current?.contains(e.target)){
setopenSlide(false)
}
}
Run Code Online (Sandbox Code Playgroud)
步骤 4:当鼠标在文档中的任意位置按下时添加事件侦听器
document.addEventListener('mousedown',closeOpenMenus)
Run Code Online (Sandbox Code Playgroud)
步骤 5:选择目标元素 (ref={variable_name})
<div ref={catMenu}>... </div>
Run Code Online (Sandbox Code Playgroud)
the*_*ude 13
您需要处理ref传递的内容,以便它实际上附加到某些东西:
const Home = forwardRef(({ open, setOpen }, ref) => {
console.log(open);
return (
<section ref={ref}>
<h1>Feels good to be home!</h1>
<button className="secondary" onClick={() => setOpen(!open)}>
Dropdown Toggle
</button>
{open && (
<ul>
<li>One</li>
<li>Two</li>
</ul>
)}
</section>
);
});
Run Code Online (Sandbox Code Playgroud)
小智 13
有点不同。从你的方法来看,但是这个钩子可以用来包装你的按钮和菜单。
/**
* This Hook can be used for detecting clicks outside the Opened Menu
*/
function useClickOutside(ref, onClickOutside) {
useEffect(() => {
/**
* Invoke Function onClick outside of element
*/
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
onClickOutside();
}
}
// Bind
document.addEventListener("mousedown", handleClickOutside);
return () => {
// dispose
document.removeEventListener("mousedown", handleClickOutside);
};
}, [ref, onClickOutside]);
}Run Code Online (Sandbox Code Playgroud)
用您的代码实现:
const Home = () => {
let [open, setOpen] = useState(false);
const wrapperRef = useRef("menu");
useClickOutside(wrapperRef, () => {
setOpen(false);
});
return (
<section>
<h1>Feels good to be home!</h1>
<div ref={wrapperRef}>
<button className="secondary" onClick={() => setOpen(!open)}>
Dropdown Toggle
</button>
{open && (
<ul>
<li>One</li>
<li>Two</li>
</ul>
)}
</div>
</section>
);
};Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
67205 次 |
| 最近记录: |