当前位置: 首页 > 编程日记 > 正文

react hooks使用_如何使用React和Hooks检测外部点击

react hooks使用

by Andrei Cacio

通过安德烈·卡西奥(Andrei Cacio)

如何使用React和Hooks检测外部点击 (How to detect an outside click with React and Hooks)

“外部点击”是什么意思? (What does “Outside Click” mean?)

You can think of it as the “anti-button”. An outside click is a way to know if the user clicks everything BUT a specific component. You may have seen this behavior when opening a dropdown menu or a dropdown list and clicking outside of it to close it.

您可以将其视为“反按钮”。 外部点击是一种了解用户是否单击所有按钮但又单击特定组件的方法。 打开下拉菜单或下拉列表并在其外部单击以将其关闭时,您可能已经看到此行为。

There are all sorts of other use cases for such a feature:

此类功能还有其他各种用例:

  • when closing dropdown lists

    关闭下拉列表时
  • when closing modal windows

    关闭模式窗口时
  • when transitioning in and out of edit mode for editable elements

    在可编辑元素的进出编辑模式转换时
  • closing

    闭幕
  • and many more…

    还有很多…

Now let’s see how we can a write a generic and reusable React component which will incorporate this behavior.

现在让我们看看如何编写一个通用且可重用的React组件,它将结合这种行为。

看起来如何 (How it will look like)

A happy flow should look like this:

一个快乐的流程应如下所示:

组件结构 (Component structure)

For this component to work we will need to attach a click event handler on the document itself. This will help us detect when we are clicking anywhere on the page. Then we will need to check if our clicked target differs from our wrapped element. So a basic structure will look like this:

为了使该组件正常工作,我们需要在文档本身上附加一个click事件处理程序。 这将帮助我们检测何时单击页面上的任意位置。 然后,我们将需要检查单击的目标是否与包装的元素不同。 因此,基本结构如下所示:

For the first example, we will start coding using the React Class style and then refactor it with the new Hooks API.

对于第一个示例,我们将开始使用React Class样式进行编码,然后使用新的Hooks API对其进行重构。

We implemented two lifecycle functions:

我们实现了两个生命周期功能:

  • componentDidMount(): will attach the event listener

    componentDidMount() :将附加事件监听器

  • componentWillUnmount(): will clean up the click handler before the component will get destroyed

    componentWillUnmount() :将在组件销毁之前清理单击处理程序

and then we render whatever that components wrap over. For our first example above it will render the <span>.

然后我们渲染组件包裹的所有内容。 对于上面的第一个示例,它将呈现<span>。

“ ClickOutside”条件 (The “ClickOutside” condition)

Now we need to check if the user clicks outside of the wrapped child. One naive solution is to compare the target element (the element that we click) with our child’s node. But, this will work only if we have a simple (single level) node as a child. If our wrapped child has more sub-nodes, then this solution will fail.

现在,我们需要检查用户是否在被包装的孩子之外单击。 一种幼稚的解决方案是将目标元素(我们单击的元素)与孩子的节点进行比较。 但是,只有当我们有一个简单的(单级)节点作为子节点时,这才起作用。 如果我们的包装子节点具有更多子节点,则此解决方案将失败。

Luckily there is a method called .contains() which tells us if a node is a child of a given node. The next step will be to gain access to our child’s node. To achieve this we will use React Refs.

幸运的是,有一个方法称为.contains() ,它告诉我们一个节点是否是给定节点的子级。 下一步将是访问我们孩子的节点。 为此,我们将使用React Refs 。

Refs are React’s way of giving us access to the raw node object. We will also use Reacts API for handling the this.props.children components. We need this API because we will inject our created ref to our wrapped child. Having this in mind our component will look like so:

引用是React使我们能够访问原始节点对象的方式。 我们还将使用Reacts API来处理this.props.children组件。 我们需要此API,因为我们会将创建的ref注入包装的孩子。 考虑到这一点,我们的组件将如下所示:

Perfect, this should work as expected. At least for our happy flow (one wrapped child). If we intend to wrap more than one node, we need to make some adjustments:

完美,这应该可以正常工作。 至少为了我们的幸福(一个被包裹的孩子)。 如果打算包装多个节点,则需要进行一些调整:

  • we need to have an array of refs (as many as our wrapped children)

    我们需要一个ref数组(与包裹的孩子一样多)
  • we need to use React.Children.map to clone each child and inject the associated ref from our private array of refs

    我们需要使用React.Children.map来克隆每个子对象,并从我们的ref私有数组中注入关联的ref

This should do just fine. Now let’s refactor this using Hooks!

这应该很好。 现在,让我们使用Hooks重构它!

钩子 (Hooks)

React 16.8 introduced a new API called Hooks. With Hooks we can write less code and get a smaller footprint on our codebase. Also, Hooks take advantage of functions which are first class citizens in JavaScript. If you are familiar with stateless functional components in React you are halfway there. Our initial refactor will look like so:

React 16.8引入了一个称为Hooks的新API。 使用Hooks,我们可以编写更少的代码,并在我们的代码库中占用更小的空间。 另外,Hooks利用了JavaScript中的一等公民功能。 如果您熟悉React中的无状态功能组件 ,那么您已经半途而废了。 我们的初始重构如下所示:

Up until now, we are still using the “old” React API to declare a simple stateless functional component. However, we still need those lifecycle functions to attach our handler on the document node.

到目前为止,我们仍在使用“旧的” React API来声明一个简单的无状态功能组件。 但是,我们仍然需要那些生命周期函数来将处理程序附加到文档节点上。

Here is where Effect hook comes in. The Effect hook will replace our “componentDidMount” and “componentWillUnmount” methods. The Effect Hook will be called right after the components renders so it will help us attach our desired handler on time. Also for the cleanup part, if the Effect hook returns a function that function will be called right before the component will be unmounted. So it is just the right time to do some cleanup. In the next refactor, things will become a bit clearer.

这是效果钩的地方 效果钩子将取代我们的“ componentDidMount ”和“ componentWillUnmount ”方法。 在组件渲染之后,将立即调用效果挂钩,这样将有助于我们按时附加所需的处理程序。 同样对于清理部分,如果Effect挂钩返回一个函数,则该函数将在卸载组件之前立即被调用。 因此,这是进行清理的正确时机。 在下一个重构中,情况将变得更加清晰。

This is the final form of our functional component using the Effect Hook. If you want to see both examples in action you can run them below. (You can default export either the Class component or the functional component and the app will behave the same.)

这是使用效果挂钩的功能组件的最终形式。 如果您想同时看到两个示例,可以在下面运行它们。 ( 您可以默认导出Class组件或功能组件,并且应用程序的行为相同。 )

结论 (Conclusion)

Even though the click outside behavior is a widely used feature, it may not be so straightforward to implement in React. With this example, I took the liberty to experiment a bit with React Hooks and build the solution in two ways to compare the two approaches. I am a big fan of functional components, and now with the help of Hooks, we can take them to the next level.

即使外部点击行为是广泛使用的功能,在React中实现起来也可能不是那么简单。 在这个示例中,我可以自由地对React Hooks进行一些实验,并以两种方式构建解决方案以比较这两种方法。 我是功能组件的忠实拥护者,现在在Hooks的帮助下,我们可以将它们提升到一个新的水平。

翻译自: https://www.freecodecamp.org/news/how-to-detect-an-outside-click-with-react-and-hooks-25dbaa30abcd/

react hooks使用

相关文章:

正则表达式(1)

正则表达式的概念 正则表达式是一个字符串&#xff0c;使用单个字符串来描述、用来定义匹配规则&#xff0c;匹配一系列符合某个句法规则的字符串。在开发中&#xff0c;正则表达式通常被用来检索、替换那些符合某个规则的文本。 正则表达式的匹配规则 字符类&#xff1a;[abc]…

Android 曲线动画animation,类似加入购物车动画

按照惯例先放效果图&#xff1a;图中小球做抛物线运动 资源图片 1.首先布局文件activity_main.xml&#xff0c;布局很简单&#xff0c;就一个测试按钮 1 <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"2 xmlns:tools"http:…

小程序音频播放报10001 解决方案 errCode:10001, errMsg:errCode:602,err:error,not found param

音频播放有两种方式&#xff1a; 第一种&#xff1a; innerAudioContext.src audioSrc;innerAudioContext.play(); 第二种&#xff1a; innerAudioContext.autoplay true;innerAudioContext.src audioSrc; 之前使用第一种&#xff0c;华为手机不能正常播放&#xff0c;…

在线学位课程_您在四年制计算机科学学位课程中学到的知识

在线学位课程by Colin Smith通过科林史密斯 您在四年制计算机科学学位课程中学到的知识 (What you learn in a 4 year Computer Science degree) I recently wrote an article on whether you need a computer science degree to get a job in tech. I thought that going ove…

Swift学习笔记-协议(Protocols)

1.0 翻译&#xff1a;geek5nan 校对&#xff1a;dabing1022 2.0 翻译&#xff1a;futantan 校对&#xff1a;小铁匠Linus 定稿&#xff1a;shanksyang 本页包含内容&#xff1a; 协议的语法&#xff08;Protocol Syntax&#xff09;对属性的规定&#xff08;Property Requireme…

JavaScript简单重写构造器的原型

1 //简单重写原型对象&#xff1a;2 3 //一个构造函数Person4 function Person(){5 6 }7 //重写Person的原型8 //把Person的原型赋值给一个新的对象 是我们重写的过程9 Person.prototype{ 10 // 对于构造器 如果我们不给他写&#xff0c;则构造器就是Object的构造器了 …

node.js cannot find module

找不到模块的解决方案 &#xff1a; 把node_module整个文件夹删掉,然后npm clean cache,看下package.json里有没有express的依赖项,有的话直接npm install,没有的话 npm install express --save。 有人说 npm clean cache 命令变成了 npm cache clean&#xff0c;可以都试一下

我在React Native中构建时获得的经验教训

by Amanda Bullington通过阿曼达布林顿(Amanda Bullington) 我在React Native中构建时获得的经验教训 (Lessons I learned while building in React Native) When I received an offer for a software engineering role to build an app in React Native, I wasn’t sure what…

【Ant Design Pro 五】箱套路由在菜单栏显示返回上一页

效果图&#xff1a; 场景&#xff1a;从菜单栏进入子页面&#xff0c;但是子页面默认不在路由显示&#xff0c;完成操作后需要返回上级页面。所以要在菜单栏中加返回的功能。 实现代码&#xff1a; import React from react; import { Button, Card, Icon } from antd; impor…

[002] The Perks of Being a Wallflower - 读后记

The Perks of Being a Wallflower 今天(2015年10月30日 18:26:17)读完"The Perks of Being a Wallflower". 本书290页,我是在小米pad上完成阅读的,epub格式,花费四天时间,每天至少5小时. 生词很多,就不一一列出了. 使用透析法并不强求完全的正确理解原文.强调完整的阅…

ios集成firebase_如何将Firebase与您的应用程序集成

ios集成firebaseYou’ve probably heard about Firebase, but may not know much about how it works and how it fits in with your application. Well, you’ve come to the right place. We’ll go over what Firebase is and how to integrate it with your Android projec…

PLSQL创建Oracle定时任务

转自&#xff1a;http://www.cnblogs.com/yx007/p/6519544.html#_label0转载于:https://www.cnblogs.com/good-tomorrow/p/7443817.html

判断h5是不是在小程序中

执行代码&#xff1a; if (ua.indexOf(MicroMessenger) -1) {//说明不在微信中// 走不在小程序的逻辑 } else {wx.miniProgram.getEnv(function(res) {if (res.miniprogram) {// 走在小程序的逻辑} else {// 走不在小程序的逻辑}}) }

CSS3关于过渡效果的问题

首先trasition:transform只是单单表示后面只要有含有的tranform的所有属性可以参与动画&#xff0c;而trasition:all表示后面所有动画属性都可以参动画&#xff0c;当父容器有relative时&#xff0c;子容器有absolute&#xff0c;子容器会跟着父容器相对定位。当你想要然后一个…

在线学位课程_如何选择计算机科学学位课程

在线学位课程by Colin Smith通过科林史密斯 如何选择计算机科学学位课程 (How to choose a Computer Science degree program) I remember combing through the countless computer science programs online and feeling a bit lost on what I should be looking for. I ended…

Dubbo 入门实例 本地伪集群测试Demo

1. 概述 Dubbo是一个分布式服务框架&#xff0c;致力于提供高性能和透明化的RPC远程服务调用方案&#xff0c;以及SOA服务治理方案 Dubbo是阿里巴巴SOA服务化治理方案的核心框架&#xff0c;每天为2,000个服务提供3,000,000,000次访问量支持&#xff0c;并被广泛应用于阿里巴…

Vue源码终笔-VNode更新与diff算法初探

写完这个就差不多了&#xff0c;准备干新项目了。 确实挺不擅长写东西&#xff0c;感觉都是罗列代码写点注释的感觉&#xff0c;这篇就简单阐述一下数据变动时DOM是如何更新的&#xff0c;主要讲解下其中的diff算法。 先来个正常的html模板&#xff1a; <body><div id…

JS获取当月每天的日期,JS获取本周每天的日期

获取当前月每天的日期&#xff0c;获取当前周每天的日期实现代码&#xff1a; 调用代码&#xff1a; console.log(-----------------, getNowM(), getWeekDay()) 结果&#xff1a;我今天是2020-2-28日 封装方法&#xff1a; function getDay(num, str) {var today new Dat…

@Scheduled注解的scheduler属性什么作用

注解是 Spring Framework 提供的一种机制,用于定义计划任务,即周期性执行的任务。 注解可以应用于方法上,以指示 Spring 容器在特定的时间间隔或按照某种调度规则来调用该方法。 属性是 注解的一个可选属性,它的作用是允许开发者指定一个自定义的 对象来控制任务的调度方式。默认情况下, 注解使用 Spring 内部的 来执行任务,但如果需要更高级的定制化需求,可以通过 属性指定一个自定义的 实现。自定义调度器:共享调度器资源:高级调度需求:假设你想使用 作为调度器,并且希望所有带有

自行车车把会吧车刮坏吗_花10分钟即可开始使用车把

自行车车把会吧车刮坏吗by Wing Puah永帕(Wing Puah) 花10分钟即可开始使用车把 (Take 10 minutes to get started with Handlebars) Nowadays front-end development is no longer about building static HTML markup and compiling SASS files. The rise of Single Page App…

每天一个linux命令(33):df 命令

linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间&#xff0c;目前还剩下多少空间等信息。 1&#xff0e;命令格式&#xff1a; df [选项] [文件] 2&#xff0e;命令功能&#xff1a; 显示指定磁盘文件的可用…

一:HDFS 用户指导

1.hdfs的牛逼特性 Hadoop, including HDFS, is well suited for distributed storage and distributed processing using commodity hardware. It is fault tolerant, scalable, and extremely simple to expand. MapReduce, well known for its simplicity and applicability …

uni-app 封装企业微信config

第一步&#xff0c;在项目根目录加一个html文件&#xff0c; index.html 代码如下&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"I…

sqoop架构_SQOOP架构的深入介绍

sqoop架构by Jayvardhan Reddy通过杰伊瓦尔丹雷迪(Jayvardhan Reddy) SQOOP架构的深入介绍 (An in-depth introduction to SQOOP architecture) Apache Sqoop is a data ingestion tool designed for efficiently transferring bulk data between Apache Hadoop and structure…

JS实现录音,播放完整代码带示例图

效果图&#xff1a; 实现代码&#xff1a; <!DOCTYPE html> <html><head><script src"recorder.js" type"text/javascript" charset"utf-8"></script><meta name"viewport" content"widthdevi…

r.json()

requests模块中&#xff0c;r.json()为Requests中内置的JSON解码器 其中只有response返回为json格式时&#xff0c;用r.json()打印出响应的内容&#xff0c; 如果response返回不为json格式&#xff0c;使用r.json()会报错 报错内容&#xff1a;ValueError: Expecting property …

冒泡排序语法树

转载于:https://www.cnblogs.com/alfredzhu/p/4939268.html

valve 的设计_向Valve Portal开发人员学习游戏设计原则

valve 的设计In this talk, Valve programers who created the game Portal discuss problems they faced in development and how they solved them. Leaning about how they solved Portal problems can give you insight into how to design better games.在本次演讲中&…

Android之控件使用

Android系统为我们提供了大量的控件&#xff0c;例如&#xff1a;开关控件、单选按钮、多选按钮、单选菜单等等&#xff0c;那么这些控件如何使用呢&#xff1f;本篇我将带领大家一道学习一下如何使用这些控件。所谓无图无真相&#xff0c;先让大家看一下效果图&#xff1a; 下…

《对软件工程课程的期望》

要学习到的能力的预期&#xff1a;要学会个人&#xff0c;结对&#xff0c;团队的代码编辑流程&#xff0c;学会和别人进行交流。 对项目课程的期望&#xff1a;希望不是枯燥的代码详解。 对项目的愿景规划&#xff1a;希望团队里的每个人都能学到有用的知识。转载于:https://w…