下面就来谈谈,怎样正确理解钩子,并且深入剖析最重要的钩子之一的useEffect()。内容会尽量通俗,让不熟悉 React 的朋友也能看懂。 一、React 的两套 API 以前,React…
React Hook 钩子检测外部点击, React Hook 钩子监控外部点击, react onClickOutside, react-click-outside-hook
1. 使用组件 react-cool-onclickoutside
react-cool-onclickoutside 是一个React 钩子 ,当用户在目标组件区域之外单击时触发回调。这是UI交互设计(IxD)的有用逻辑,例如关闭下拉菜单,模态或工具提示等。帮助大家❤️。
特征
- React监听基于React hook的外部点击 。
- Support♀️支持多个引用,以涵盖更多用例。
- ?使用 被动事件侦听 器改善滚动性能。
- ️滚动条可以从外部点击的回调中排除。
- the 在事件循环中忽略某些元素。
- ?使您可以在需要时停止监听外部喀哒声。
- for由于某些原因支持自定义引用 。
- ?支持 TypeScript 类型定义。
- Server️服务器端渲染友好。
- ?微小的大小(压缩后约为1.4KB)。除了反应之外,没有外部依赖性。
您还可以安装通过npm分发的此软件包 。
$ yarn add react-cool-onclickoutside # or $ npm install --save react-cool-onclickoutside
有关更多用法的详细信息,请查看项目的GitHub页面:https : //github.com/wellyshen/react-cool-onclickoutside
快速入门(演示代码)
常见用例。
支持多个裁判。仅当用户在注册的组件之外单击时才触发回调。
通过CSS类名忽略元素
您可以 通过ignore-onclickoutside CSS类名称告诉 react-cool-onclickoutside在事件循环期间忽略某些元素 。如果要显式控制类名,请使用 ignoreClass 选项。
import React, { useState } from "react"; import useOnclickOutside from "react-cool-onclickoutside"; // Use default CSS class name const App = () => { const ref = useOnclickOutside(() => { // Do something... }); return ( <div> <div ref={ref}>I'm a ?</div> <div>Click me will trigger the event's callback</div> <div className="ignore-onclickoutside"> Click me won't trigger the event's callback </div> </div> ); }; // Use the CSS class name that you defined const App = () => { const ref = useOnclickOutside( () => { // Do something... }, { ignoreClass: "my-ignore-class" } ); return ( <div> <div ref={ref}>I'm a ?</div> <div>Click me will trigger the event's callback</div> <div className="my-ignore-class"> Click me won't trigger the event's callback </div> </div> ); };
禁用事件监听器
如果出于性能原因要禁用事件侦听器或满足某些用例。我们 为您提供了 禁用选项。将其设置为 true后,将不会触发回调。
import React, { useState } from "react"; import useOnclickOutside from "react-cool-onclickoutside"; const App = () => { const [disabled, setDisabled] = useState(false); const ref = useOnclickOutside( () => { // Do something... }, { disabled } ); const handleBtnClick = () => { setDisabled(true); }; return ( <div> <button onClick={handleBtnClick}> Stop listening for outside clicks </button> <div ref={ref}>I'm a ?</div> </div> ); };
2. React Hooks – 使用外部点击
描述
一个 hook,可以处理包装在组建外部的点击事件。
- 创建一个自定义的 hook,使用
ref
和callback
来处理click
事件 - 使用
React.useEffect()
hook 来添加或清除click
事件 - 使用
React.useRef()
hook 为你的点击组建创建一个ref
,并将他作为参数传递给useClickInside
hook
实现
const useClickOutside = (ref, callback) => { const handleClick = e => { if (ref.current && !ref.current.contains(e.target)) { callback(); } }; React.useEffect(() => { document.addEventListener('click', handleClick); return () => { document.removeEventListener('click', handleClick); }; }); };
使用
const ClickBox = ({ onClickOutside }) => { const clickRef = React.useRef(); useClickOutside(clickRef, onClickOutside); return ( <div className="click-box" ref={clickRef} style={{ border: '2px dashed orangered', height: 200, width: 400, display: 'flex', justifyContent: 'center', alignItems: 'center' }} > <p>Click out of this element</p> </div> ); }; ReactDOM.render( <ClickBox onClickOutside={() => alert('click outside')} />, document.getElementById('root') );
3. React Hooks – 颜色选择器
让我们来看一个先前的示例,其中我们在react中实现了颜色选择器。现在,我们将在输入字段的单击上显示一个颜色选择器,并在检测到颜色选择器外部的单击时将其隐藏。
首先,我们必须创建一个自定义钩子以检测单击事件。使用以下代码创建自定义钩子。
useVisible.js
import { useState, useRef, useEffect } from "react"; function useVisible(initialIsVisible) { const [isVisible, setIsVisible] = useState(initialIsVisible); const ref = useRef(null); const handleClickOutside = (event) => { if (ref.current && !ref.current.contains(event.target)) { setIsVisible(false); } }; useEffect(() => { document.addEventListener('click', handleClickOutside, true); return () => { document.removeEventListener('click', handleClickOutside, true); }; }, []); return { ref, isVisible, setIsVisible }; } export default useVisible;
使用App.js
文件中的以上钩子来管理单击时的显示/隐藏颜色选择器。
import React, { useState } from 'react'; import { SketchPicker } from 'react-color'; import useVisible from './useVisible'; function App() { const [colorHexCode, setColorHexCode] = useState('#000000'); const { ref, isVisible, setIsVisible } = useVisible(false); return ( <div className="App"> <h3>React color picker - <a href="https://www.cluemediator.com">Clue Mediator</a></h3> <div> <b>Selected Hex Color: </b> <span className="color-box" style={{ background: colorHexCode }}></span> {colorHexCode} </div> <br /> <input type="text" readOnly value={colorHexCode} onClick={e => setIsVisible(!isVisible)} /> {isVisible && <div style={{ position: 'absolute' }} ref={ref}> <SketchPicker color={colorHexCode} onChange={e => setColorHexCode(e.hex)} /> </div>} </div> ); } export default App;
我们还将在框中显示选定的颜色以及实时取景的颜色代码。
输出量
运行项目并在浏览器中签出输出。
4. React Hooks – 控制model
import { useState, useEffect, useRef } from 'react'; // Usage function App() { // Create a ref that we add to the element for which we want to detect outside clicks const ref = useRef(); // State for our modal const [isModalOpen, setModalOpen] = useState(false); // Call hook passing in the ref and a function to call on outside click useOnClickOutside(ref, () => setModalOpen(false)); return ( <div> {isModalOpen ? ( <div ref={ref}> ? Hey, I'm a modal. Click anywhere outside of me to close. </div> ) : ( <button onClick={() => setModalOpen(true)}>Open Modal</button> )} </div> ); } // Hook function useOnClickOutside(ref, handler) { useEffect( () => { const listener = event => { // Do nothing if clicking ref's element or descendent elements if (!ref.current || ref.current.contains(event.target)) { return; } handler(event); }; document.addEventListener('mousedown', listener); document.addEventListener('touchstart', listener); return () => { document.removeEventListener('mousedown', listener); document.removeEventListener('touchstart', listener); }; }, // Add ref and handler to effect dependencies // It's worth noting that because passed in handler is a new ... // ... function on every render that will cause this effect ... // ... callback/cleanup to run every render. It's not a big deal ... // ... but to optimize you can wrap handler in useCallback before ... // ... passing it into this hook. [ref, handler] ); }
效果:
本文:React Hook 钩子检测外部点击, React Hook 钩子监控外部点击, react onClickOutside, react-click-outside-hook