我有这个组件,我使用useRef和useEffect来处理弹出窗口外的点击,这样我就可以关闭它。
我已经添加了useEffect需要的两个依赖项,但我得到了以下错误:
The 'handleClickOutside' function makes the dependencies of useEffect Hook (at line 117) change on every render. Move it inside the useEffect callback. Alternatively, wrap the 'handleClickOutside' definition into its own useCallback()
正如您在这里看到的,我正在添加这两个依赖项,但它仍然抛出此错误/警告:
useEffect(() => {
if (isOverlayOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isOverlayOpen, handleClickOutside]);有什么办法解决这个问题吗?
在这里,我的代码框:https://codesandbox.io/s/laughing-newton-1gcme?fontsize=14&hidenavigation=1&theme=dark问题在src/components/Type正前方第100行中。
在这里,组件代码:
function ResultsOverlay({
isOpen,
items,
selectItem,
highlightedOption,
setIsOverlayOpen,
isOverlayOpen
}) {
const node = useRef();
const handleClickOutside = e => {
if (node.current.contains(e.target)) {
return;
}
setIsOverlayOpen(false);
};
useEffect(() => {
if (isOverlayOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isOverlayOpen]);
function matchedOptionsClass(index) {
if (highlightedOption === index) {
return "ph4 list f3 sesame-red list-item pointer";
}
return "ph4 list sesame-blue list-item pointer";
}
if (isOpen) {
return (
<div className="absolute" ref={node}>
<ul className="w5 mt0 pa0 h5 overflow-scroll shadow-5 dib">
{items &&
items.map((item, index) => (
<li
onClick={() => selectItem(item)}
className={matchedOptionsClass(index)}
>
{item}
</li>
))}
</ul>
</div>
);
} else {
return null;
}
}发布于 2019-11-21 14:39:29
两个问题:
首先,执行linst告诉您的操作,并将函数定义移到效果中。
useEffect(() => {
const handleClickOutside = e => {
if (node.current.contains(e.target)) {
return;
}
setIsOverlayOpen(false);
};
if (isOverlayOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isOverlayOpen]);第二,setIsOverlayOpen是通过props提供的回调,因此它没有稳定的签名,并在每次呈现时触发效果。
假设setIsOverlayOpen是来自useState的setter,并且不需要更改它的签名,您可以通过使用useCallback将处理程序包装到一个属性依赖检查层来解决这一问题
const stableHandler = useCallback(setIsOverlayOpen, [])
useEffect(() => {
const handleClickOutside = e => {
if (node.current.contains(e.target)) {
return;
}
stableHandler(false);
};
if (isOverlayOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isOverlayOpen, stableHandler]);https://stackoverflow.com/questions/58977389
复制相似问题