优雅的在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 ...
随机推荐
- JS继承 小白文
继承我的理解是 一个对象 能够使用另一个对象的方法和属性 继承需要一个父类构造函数 一.通过原型链继承 通过 创建一个 Person 的实例对象,该对象身上 不仅有 name 和 age 等方法, 也 ...
- 牛客网数据库SQL实战解析(1-10题)
牛客网SQL刷题地址: https://www.nowcoder.com/ta/sql?page=0 牛客网数据库SQL实战解析(01-10题): https://blog.csdn.net/u010 ...
- 运用sed命令高效地删除文件的特定行
运用 sed 命令高效地删除文件的特定行 正常来说,我们想要删除文件中的某些行内容,一般都是先打开这个文件,然后找到要删除的内容,再然后选中这些行并按删除键进行删除,这在数据量很少时是没有问题的.但是 ...
- 快醒醒,C# 9 中又来了一堆关键词 init,record,with
一:背景 1. 讲故事 .NET5 终于在 2020-08-25 也就是前天发布了第八个预览版,这么多的预览版搞得我都麻木了,接踵而来的就是更多的新特性加入到了 C# 9 中,既然还想呆在这条船上,得 ...
- zero:如何找到SEO流量的突破口
http://www.wocaoseo.com/thread-326-1-1.html 之前一篇文章已有提到过,SEO可以分为两个阶段: 一个阶段是了解点SEO知识,然后就到网站上去找页面,看哪些招式 ...
- 牛哄哄的celery
一.什么是Celery 1.1.celery是什么 Celery是一个简单.灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,同时也支持任务调度. Celery的架构由三部分组成, ...
- Cython编译独立的可执行文件
cython --embed -o hello.c hello.pygcc hello.c -o hello -I /Library/Frameworks/Python.framework/Versi ...
- 笔记-Linux 内存优化
1.清理前内存使用情况 free -m2.开始清理 echo 1 > /proc/sys/vm/drop_caches 3.清理后内存使用情况 free -m 4.完成! 查看内存条数命令: d ...
- 剑指 Offer 19. 正则表达式匹配
题目描述 请实现一个函数用来匹配包含'. '和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次).在本题中,匹配是指字符串的所有字符匹配整个模式. ...
- redis基础数据结构及编码方式
redis基础数据结构和编码方式 一.基础数据结构 1)简单动态字符串 2)双端链表 3)字典 4)跳跃表 5)整数集合 6)压缩列表 二.对象类型与编码 在redis的数据库中创建一个新的键值对时, ...