优雅的在React组件中注册事件
前言
在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>
);
}
}
总结
这种小技巧提高了开发效率,少写了很多代码,可以在项目代码中尝试。
来源:https://segmentfault.com/a/1190000017348517
优雅的在React组件中注册事件的更多相关文章
- 如何优雅的设计React组件
如何优雅的设计 React 组件 如今的 web 前端已被 React.Vue 和 Angular 三分天下,一统江山十几年的 jQuery 显然已经很难满足现在的开发模式.那么,为什么大家会觉得 j ...
- 如何优雅地在React项目中使用Redux
前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...
- 规避 React 组件中的 bind(this)
React 组件中处理 onClick 类似事件绑定的时候,是需要显式给处理器绑定上下文(context)的,这一度使代码变得冗余和难看. 请看如下的示例: class App extends Com ...
- 优雅的在React项目中使用Redux
概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与React没有任何关系,其他UI框架也可以使用Redux react-redux React插件,作用:方便在 ...
- 【React】282- 在 React 组件中使用 Refs 指南
英文:Yomi Eluwande 译文:joking_zhang https://segmentfault.com/a/1190000019277029 使用 React 时,我们的默认思维方式应该 ...
- React组件中对子组件children进行加强
React组件中对子组件children进行加强 问题 如何对组件的children进行加强,如:添加属性.绑定事件,而不是使用<div>{this.props.children}< ...
- 在 React 组件中使用 Refs 指南
原文:Fullstack React's Guide to using Refs in React Components作者:Yomi Eluwande译者:博轩 译文:https://segment ...
- react组件中的constructor和super小知识
react组件中的constructor和super小知识 1.react中用class申明的类一些小知识 如上图:类Child是通过class关键字申明,并且继承于类React. A.Child的类 ...
- React组件中的key
React组件中的key 一.key的作用 react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key props),而是给reac ...
随机推荐
- 【C艹】关于sort用法之重构cmp(comp)函数的笔记
众所周知,balabalabalabala············. 所以掌握sort函数(库文件:<algorithm>)的用法还是很有必要的. 一般选手只会简单地用用sort排一排数组 ...
- 关于函数式接口, printable 自定义
这段代码在jdk1.8可以使用, 由于我是jdk14, 会报错. 这里可以优化, lambda表达式进一步优化写为: printString(System.Out::println); 注意案例版 ...
- go微服务系列(四) - http api中引入protobuf
1. protobuf相关依赖安装 2. 改造之前的client 2.1 新建proto文件 2.2 运行protoc命令生成go文件 2.3 然后把原来的map修改成具体的类型就可以了 3. 处理j ...
- e3mall商城总结13之订单确认(有BUG)
说在前面的话 上一节说了购物车的生成,本节主要说了在购物车的列表上去结算,从而生成一个未支付的订单,生成的订单默认状态为1, 题目说的BUG是因为所有数据都是通过前端向后端生成的,包括订单的金额.因此 ...
- 关于js与jquery中的文档加载
jquery中的$(document).ready()类似于javascript中的window.onload(),但是其中还是有很大区别的 1.jquery中的可以简化为$().ready(),$( ...
- Django:给requests发送请求功能 套一层衣服。
个人的疑问
- My Github Repository
最近在Github上整了个Repository来保存打过的比赛的代码,包括Codeforces,Google Code Jam和Google Kick Start等,之后应该也会搞一点刷题的代码. 之 ...
- JS中的数组,添加删除元素,判断是否存在一个值的方法总结
一.添加元素: 1:在最后添加,返回数组长度:arr.push(...); 2:在最前面添加,返回数组长度:arr.unshift(...); 3:在指定位置添加,没有返回值:arr[i] = xxx ...
- Spring security OAuth2.0认证授权学习第一天(基础概念-认证授权会话)
这段时间没有学习,可能是因为最近工作比较忙,每天回来都晚上11点多了,但是还是要学习的,进过和我的领导确认,在当前公司的技术架构方面,将持续使用Spring security,暂不做Shiro的考虑, ...
- Zabbix下查看参数的小技巧
我们在管理.维护Zabbix的时候,经常需要查看配置文件下的一些参数信息.下面介绍一些常用的小技巧. 1:我想知道zabbix_server.conf文件中配置了那些参数. # grep '^[a-Z ...