[英]Using a higher order component to add event listeners per component
我的应用程序中有一些组件,可以处理来自键盘的一些用户输入。 为此,我创建了以下功能:
export default function withKeydownEventHandler (handler) {
id = id + 1
return lifecycle({
componentWillMount () {
$(window).on(`keydown.${id}`, evt => handler(evt))
},
componentWillUnmount () {
$(window).off(`keydown.${id}`)
}
})
}
这样可以正常工作,但处理程序同时被激活用于不同的组件。 因此,如果我的处理程序在每个组件中执行不同的操作,每当我单击一个按钮时,它将同时从两个组件中触发。 此外,一旦卸下一个组件,HoC将不再起作用。
例如,假设我有以下两个容器:
export default compose(
withKeydownEventHandler((evt, props) => {
console.warn('hi from Component 1')
}),
withProps(() => {
// stuff
})
)(Component1)
export default compose(
withKeydownEventHandler((evt, props) => {
console.warn('hi from Component 2')
}),
withProps(() => {
// stuff
})
)(Component2)
如果我点击整个应用程序中的任何按钮,我将得到以下输出:
来自组件1
来自组件2
另一方面,一旦其中一个组件卸载,我就不再发生任何事件。
我究竟做错了什么? 如何通过可在整个应用程序中重复使用的HoC获取keydown事件处理程序?
首先,我可以提请您注意您的id
被设置为全局变量。 您确定要将这样的变量名称作为全局变量吗?
其次,你使用$(window).on('keydown.${id}', evt => handler(evt))
将keydown事件绑定到windows,这解释了你不想要的行为。 您需要将其与您希望处理程序操作的特定组件绑定一次。
最后,为什么不创建一个HOC类并有条件地添加事件监听器? 如下:
// src/Hoc.jsx
export default function(WrapperComponent) {
return class extends Component {
componentWillMount () {
const { onKeyDownHandler } = this.props;
if (isKeyDownEventNeeded) {
this.comp.addEventListener("keydown", onKeyDownHandler);
}
}
componentWillUnmount () {
const { onKeyDownHandler } = this.props;
if (isKeyDownEventNeeded) {
this.comp.removeEventListener("keydown", onKeyDownHandler);
}
}
render() {
const { onKeyDownHandler } = this.props;
if (onKeyDownHandler) {
// a "ref" callback which assigns the mounted
// Element to a prop "comp" whicu can be used later to add the DOM listener to.
return <WrapperComponent ref={elem => this.comp = elem} {...this.props} />
}
return <WrapperComponent {...this.props} />
}
}
export default HighOrderComponent;
然后
// somewhere-else.js
import highOrderComponent from 'src/Hoc'
highOrderComponent(<Component1 onKeyDownHandler={() => console.log('hey, Component 1'} />
highOrderComponent(<Component2 onKeyDownHandler={() => console.log('hey, Component 2'} />
有关如何查看此答案的更多信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.