我有一个自定义钩子,可以设置多个按预期工作的事件侦听器。但是我注意到,事件监听器在重新渲染时不会被删除。我做错了什么(代码后半部分的事件监听器)?也就是说,我在锚标记事件中注意到了它;handleLink
。
export default function useCursorSelector(
selectorRef: React.RefObject<HTMLElement>,
onClickLink: (url: string) => void,
onSelect: (text: string) => void
) {
const classes = useStyles();
const handleSelection = React.useCallback(
(event: MouseEvent) => {
const selection: Selection | null = window.getSelection();
if (selection) {
const text = fullStringSelection(selection);
selection.removeAllRanges();
onSelect(text);
}
event.stopPropagation();
},
[onSelect]
);
const handleLink = React.useCallback(
(a: HTMLAnchorElement) => (e: MouseEvent) => {
e.preventDefault();
onClickLink(a.href);
},
[onClickLink]
);
React.useEffect(() => {
if (selectorRef.current) {
wrapInSpans(selectorRef.current, classes.highlight, onClickLink);
}
}, [classes.highlight, selectorRef, onClickLink]);
React.useEffect(() => {
selectorRef!
.current!.querySelectorAll(`.${classes.highlight}`)
.forEach((e: any) => {
e.addEventListener("mouseup", handleSelection);
});
selectorRef!
.current!.querySelectorAll(`a`)
.forEach((a: HTMLAnchorElement) => {
a.addEventListener("click", handleLink(a));
});
return () => {
selectorRef!
.current!.querySelectorAll(`.${classes.highlight}`)
.forEach((e: any) => {
e.removeEventListener("mouseup", handleSelection);
});
selectorRef!
.current!.querySelectorAll(`a`)
.forEach((a: HTMLAnchorElement) => {
a.removeEventListener("click", handleLink(a));
});
};
}, [handleSelection, handleLink, classes.highlight, selectorRef]);
}
每次调用时,handleLink(a)
您都将创建一个新的匿名函数用作事件处理程序的回调。
调用时,removeEventListener
您应该传递对用于附加事件的同一回调的引用,但是,每次调用时,handleLink
您都在创建一个新的匿名函数。
您可以以某种方式存储对您所创建或重写的回调的引用,handleLink
从而根本不需要传递该元素。
const handleLink = React.useCallback((e: MouseEvent) => {
e.preventDefault();
onClickLink(e.currentTarget.href);
}, [onClickLink]);
...
React.useEffect(() => {
selectorRef!
.current!.querySelectorAll(`.${classes.highlight}`)
.forEach((e: any) => {
e.addEventListener("mouseup", handleSelection);
});
selectorRef!
.current!.querySelectorAll(`a`)
.forEach((a: HTMLAnchorElement) => {
a.addEventListener("click", handleLink);
});
return () => {
selectorRef!
.current!.querySelectorAll(`.${classes.highlight}`)
.forEach((e: any) => {
e.removeEventListener("mouseup", handleSelection);
});
selectorRef!
.current!.querySelectorAll(`a`)
.forEach((a: HTMLAnchorElement) => {
a.removeEventListener("click", handleLink);
});
};
}, [handleSelection, handleLink, classes.highlight, selectorRef]);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句