前言

在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组件中注册事件的更多相关文章

  1. 如何优雅的设计React组件

    如何优雅的设计 React 组件 如今的 web 前端已被 React.Vue 和 Angular 三分天下,一统江山十几年的 jQuery 显然已经很难满足现在的开发模式.那么,为什么大家会觉得 j ...

  2. 如何优雅地在React项目中使用Redux

    前言 或许你当前的项目还没有到应用Redux的程度,但提前了解一下也没有坏处,本文不会安利大家使用Redux 概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与 ...

  3. 规避 React 组件中的 bind(this)

    React 组件中处理 onClick 类似事件绑定的时候,是需要显式给处理器绑定上下文(context)的,这一度使代码变得冗余和难看. 请看如下的示例: class App extends Com ...

  4. 优雅的在React项目中使用Redux

    概念 首先我们会用到哪些框架和工具呢? React UI框架 Redux 状态管理工具,与React没有任何关系,其他UI框架也可以使用Redux react-redux React插件,作用:方便在 ...

  5. 【React】282- 在 React 组件中使用 Refs 指南

    英文:Yomi Eluwande  译文:joking_zhang https://segmentfault.com/a/1190000019277029 使用 React 时,我们的默认思维方式应该 ...

  6. React组件中对子组件children进行加强

    React组件中对子组件children进行加强 问题 如何对组件的children进行加强,如:添加属性.绑定事件,而不是使用<div>{this.props.children}< ...

  7. 在 React 组件中使用 Refs 指南

    原文:Fullstack React's Guide to using Refs in React Components作者:Yomi Eluwande译者:博轩 译文:https://segment ...

  8. react组件中的constructor和super小知识

    react组件中的constructor和super小知识 1.react中用class申明的类一些小知识 如上图:类Child是通过class关键字申明,并且继承于类React. A.Child的类 ...

  9. React组件中的key

    React组件中的key 一.key的作用 react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key props),而是给reac ...

随机推荐

  1. 【C艹】关于sort用法之重构cmp(comp)函数的笔记

    众所周知,balabalabalabala············. 所以掌握sort函数(库文件:<algorithm>)的用法还是很有必要的. 一般选手只会简单地用用sort排一排数组 ...

  2. 关于函数式接口, printable 自定义

    这段代码在jdk1.8可以使用,  由于我是jdk14, 会报错. 这里可以优化, lambda表达式进一步优化写为:  printString(System.Out::println); 注意案例版 ...

  3. go微服务系列(四) - http api中引入protobuf

    1. protobuf相关依赖安装 2. 改造之前的client 2.1 新建proto文件 2.2 运行protoc命令生成go文件 2.3 然后把原来的map修改成具体的类型就可以了 3. 处理j ...

  4. e3mall商城总结13之订单确认(有BUG)

    说在前面的话 上一节说了购物车的生成,本节主要说了在购物车的列表上去结算,从而生成一个未支付的订单,生成的订单默认状态为1, 题目说的BUG是因为所有数据都是通过前端向后端生成的,包括订单的金额.因此 ...

  5. 关于js与jquery中的文档加载

    jquery中的$(document).ready()类似于javascript中的window.onload(),但是其中还是有很大区别的 1.jquery中的可以简化为$().ready(),$( ...

  6. Django:给requests发送请求功能 套一层衣服。

    个人的疑问

  7. My Github Repository

    最近在Github上整了个Repository来保存打过的比赛的代码,包括Codeforces,Google Code Jam和Google Kick Start等,之后应该也会搞一点刷题的代码. 之 ...

  8. JS中的数组,添加删除元素,判断是否存在一个值的方法总结

    一.添加元素: 1:在最后添加,返回数组长度:arr.push(...); 2:在最前面添加,返回数组长度:arr.unshift(...); 3:在指定位置添加,没有返回值:arr[i] = xxx ...

  9. Spring security OAuth2.0认证授权学习第一天(基础概念-认证授权会话)

    这段时间没有学习,可能是因为最近工作比较忙,每天回来都晚上11点多了,但是还是要学习的,进过和我的领导确认,在当前公司的技术架构方面,将持续使用Spring security,暂不做Shiro的考虑, ...

  10. Zabbix下查看参数的小技巧

    我们在管理.维护Zabbix的时候,经常需要查看配置文件下的一些参数信息.下面介绍一些常用的小技巧. 1:我想知道zabbix_server.conf文件中配置了那些参数. # grep '^[a-Z ...