媒介
在React的开辟中,我们常常需要在 window 上注册一些事宜, 比方按下 Esc 封闭弹窗, 按上下键选中列表内容等等。比较罕见的操纵是在组件 mount 的时刻去 window 上监听一个事宜, 在组件 unmount 的时刻住手监听事宜。下面给人人引见几个骚操纵。
WindowEventHandler
我们建立一个 WindowEventHandler 组件, 内容以下
import PropTypes from 'prop-types';
import { Component, PureComponent } from 'react';
export default class WindowEventHandler extends (PureComponent || Component) {
static propTypes = {
eventName: PropTypes.string.isRequired,
callback: PropTypes.func.isRequired,
useCapture: PropTypes.bool,
};
static defaultProps = {
useCapture: false,
};
componentDidMount() {
const { eventName, callback, useCapture } = this.props;
window.addEventListener(eventName, callback, useCapture);
}
componentWillUnmount() {
const { eventName, callback, useCapture } = this.props;
window.removeEventListener(eventName, callback, useCapture);
}
render() {
return null;
}
}
如今比方我们想在组件A中监听 window 的 resize 事宜,我们在 A 组件中能够这么写
export default class A extends (PureComponent || Component) {
handleResize = () => {
// dosomething...
}
render() {
return (
<div>
我是组件A
<WindowEventHandler eventName="resize" callback={this.handleResize} />
</div>
);
}
}
如许我们在多个组件中就不需要每次都要写 mount 和 unmount 的钩子函数了,省了许多事变。
运用装潢器
我们能够给组件写一个一致的装潢器,和之前一样传入事宜名和方法名就能够监听,比及组件卸载的时刻就住手监听,代码以下
export default function windowEventDecorator(eventName, fn) {
return function decorator(Component) {
return (...args) => {
const inst = new Component(...args);
const instComponentDidMount = inst.componentDidMount ? inst.componentDidMount.bind(inst) : undefined;
const instComponentWillUnmount = inst.instComponentWillUnmount ? inst.componentWillUnmount.bind(inst) : undefined;
const callback = (e) => {
typeof inst[fn] === 'function' && inst[fn]();
};
inst.componentDidMount = () => {
instComponentDidMount && instComponentDidMount();
document.body.addEventListener(eventName, callback, true);
};
inst.componentWillUnmount = () => {
instComponentWillUnmount && instComponentWillUnmount();
document.body.removeEventListener(eventName, callback, true);
};
return inst;
};
};
}
相似如许的装潢器,同理我们想在 A 中监听 window 的 resize 事宜,能够这么写
@windowEventDecorator('resize', 'handleResize');
export default class A extends (PureComponent || Component) {
handleResize = () => {
// dosomething...
}
render() {
return (
<div>
我是组件A
</div>
);
}
}
总结
这类小技能提高了开辟效力,少写了许多代码,能够在项目代码中尝试。