【发布时间】:2021-05-11 14:31:09
【问题描述】:
如果输入组件有任何锚标记,我正在创建一个 HOC,它添加了从外部打开超链接的功能。
以下是 HOC:
export const withExternalLink = ( Component, rootId = false ) => ( props ) => {
function openLinksExternally( e, rootId ) {
const rootHtml = e.target.closest( rootId );
if ( ! rootHtml ) {
return;
}
const anchor = e.target.closest( 'a' );
if ( anchor ) {
e.preventDefault();
/**
* Logic to open link externally.
*/
}
}
useEffect( () => {
document.addEventListener( 'click', ( e ) => openLinksExternally( e, rootId ) );
return () => document.removeEventListener( 'click', ( e ) => openLinksExternally( e, rootId ) );
}, [] );
return <Component { ...props } />;
};
用法:
const CardWithExternalLinks = withExternalLink( Card );
如果<CardWithExternalLinks /> 在页面上使用一次,则此方法有效。但是如果我们使用它n 次,那么useEffect() 运行n 次,然后添加事件监听器n 次。
我能够通过将openLinksExternally() 移到withExternalLink() 之外来解决它,这样只有1 个对该函数的引用。但问题是我必须使用匿名函数来添加事件监听器,因为我必须将rootId 参数传递给openLinksExternally()。
由于我使用了匿名函数,因此为每个useEffect() 注册了一个新的事件侦听器,并且每当单击<a/> 标记时,openLinksExternally() 就会运行n 次。
有没有办法更好地实现这一点,以便点击运行一次?
【问题讨论】:
标签: reactjs addeventlistener higher-order-components