我正在尝试实现一个HOC,如果用户单击外部,它将卸载组件。这是我的HOC ClickOutsideHOC.js
import React from 'react'
const ClickOutsideHOC = props => {
const {
callback,
identifier
} = props
React.useEffect(() => {
document.addEventListener('click', handleDOMClickHOC(identifier, callback))
return () => document.removeEventListener('click', handleDOMClickHOC) // this needs repair
}, [])
return props.children
}
const handleDOMClickHOC = (identifier, callback) => event => {
const elem = document.querySelector(identifier)
if (elem && !elem.contains(event.target))
callback(false)
}
export default ClickOutsideHOC`
这就是我使用HOC的方式。 SomeOtherComponent.js
const [toggleValue, setToggleValue] = React.useState(false)
//
//
//
{
toggleValue ?
<ClickOutsideHOC
identifier=".some-class-name"
callback={setToggleValue}
>
<div className="some-class-name">
</div>
</ClickOutsideHOC>: ''
}
这似乎有效。问题是我不确定删除事件处理程序的过程。 handleDOMClickHOC
函数正在返回一个新的函数引用,但我没有将其存储在任何地方。我认为这会导致内存泄漏。我可以在chrome调试器控制台的Event Listeners
标签中看到多个处理程序已注册到DOM。如何编写此代码,以确保不会因未订阅的事件处理程序而导致内存泄漏?
答案 0 :(得分:1)
因此,如果您知道需要引用才能删除侦听器,为什么不创建它呢?
import React from 'react'
const handleDOMClickHOC = (identifier, callback) => event => {
const elem = document.querySelector(identifier)
if (elem && !elem.contains(event.target))
callback(false)
}
const ClickOutsideHOC = props => {
const {
callback,
identifier
} = props
const listener = handleDOMClickHOC(identifier, callback);
React.useEffect(() => {
document.addEventListener('click', listener)
return () => document.removeEventListener('click', listener)
}, [])
return props.children
}
export default ClickOutsideHOC`
答案 1 :(得分:0)
您只需将所有必要的参数与call
绑定:
通过这种方式,您将始终将事件,参数和其他内容传递给Handler。
React.useEffect(() => {
document.addEventListener('click', handleDOMClickHOC.call(null, identifier, callback) } )
return () => document.removeEventListener('click', handleDOMClickHOC) // this needs repair
}, [])