reactjs - 使用 eventHandler 构建下拉列表。如何构造钩子+事件处理程序
问题描述
我正在使用反应和功能组件构建一个简单的下拉列表。关于奇怪的行为,我遇到的就是我们必须思考变戏法和状态的方式。这是我的组件的简化版本:
export default function App() {
const [show, setShow] = useState(false);
const selectElement = useRef(null);
const handleToggle = (e) => {
if (selectElement) {
if (!selectElement.current.contains(e.target)) {
setShow(!show);
}
}
};
useEffect(() => {
document.addEventListener("click", handleToggle, false);
return () => document.removeEventListener("click", handleToggle, false);
}, []);
return (
<div className="App">
<div ref={selectElement} className="comp">
<h1 onClick={() => setShow(!show)}>Select</h1>
{show && (
<div>
<div>Inner 1</div>
<div>Inner 2</div>
</div>
)}
</div>
</div>
);
}
此组件行为错误,无法正确切换下拉菜单。效果处理程序在第一次渲染时注册并包含第一次渲染的状态(如果我在这里没有错的话)。注册的函数将不会收到状态更新。这导致了错误。
我不确定解决此问题的最佳方法是什么。目前,我决定简单地从useEffect
钩子中删除依赖数组,以便在每次渲染/清理时创建和销毁效果处理程序。
我还创建了一个沙盒,因此我的问题变得更加具体。
解决方案
我认为这段代码将帮助您解决问题。
export default function App() {
const [show, setShow] = useState(false);
const selectElement = useRef(null);
const handleToggle = (e) => {
if (selectElement) {
if (!selectElement.current.contains(e.target)) {
setShow(false);
document.removeEventListener("click", handleToggle, false);
}
}
};
const handleClick = (e) => {
setShow(true)
document.addEventListener("click", handleToggle, false);
};
return (
<div className="App">
<div ref={selectElement} className="comp">
<h1 onClick={handleClick}>Select</h1>
{show && (
<div>
<div>Inner 1</div>
<div>Inner 2</div>
</div>
)}
</div>
</div>
);
}
推荐阅读
- angular - 支持多种日期格式的 Angular 日期选择器
- apache-spark - 读取或写入 Parquet 格式数据时出错
- node.js - 将 TypeScript 与 Express 和静态文件一起使用
- python - 如何在烧瓶应用程序中管理多个相似的应用程序路由?
- python - pd.read_csv 显示索引和列名但没有值
- sql - 将 azure sql 数据库还原到托管实例
- reactjs - 如何删除在反应上下文警告之外调用的computedFn
- c++ - 关于用括号括起来的声明类型是什么的问题
- java - 如何根据偏航,俯仰和滚动值旋转处理中的对象
- ios - 安装了 FB 应用程序的 SwiftUI 自定义 Facebook 登录