J'essaie d'utiliser des hooks de réaction pour déterminer si un utilisateur a cliqué en dehors d'un élément. J'utilise useRef
pour obtenir une référence à l'élément.
Quelqu'un peut-il voir comment résoudre ce problème. Je reçois les erreurs suivantes et je suis les réponses d'ici .
La propriété 'contient' n'existe pas sur le type 'RefObject'
Cette erreur ci-dessus semble être un problème de typographie.
Il existe un code sandbox ici avec une erreur différente.
Dans les deux cas, cela ne fonctionne pas.
import React, { useState, useEffect, useRef } from 'react'; import ReactDOM from 'react-dom'; const Menu = () => { const wrapperRef = useRef<HTMLDivElement>(null); const [isVisible, setIsVisible] = useState(true); // below is the same as componentDidMount and componentDidUnmount useEffect(() => { document.addEventListener('click', handleClickOutside, true); return () => { document.removeEventListener('click', handleClickOutside, true); }; }, []); const handleClickOutside = event => { const domNode = ReactDOM.findDOMNode(wrapperRef); // error is coming from below if (!domNode || !domNode.contains(event.target)) { setIsVisible(false); } } return( <div ref={wrapperRef}> <p>Menu</p> </div> ) }
3 Réponses :
l ' API useRef doit être utilisée comme ceci:
import React, { useState, useRef, useEffect } from "react"; import ReactDOM from "react-dom"; function App() { const wrapperRef = useRef(null); const [isVisible, setIsVisible] = useState(true); // below is the same as componentDidMount and componentDidUnmount useEffect(() => { document.addEventListener("click", handleClickOutside, false); return () => { document.removeEventListener("click", handleClickOutside, false); }; }, []); const handleClickOutside = event => { if (wrapperRef.current && !wrapperRef.current.contains(event.target)) { setIsVisible(false); } }; return ( isVisible && ( <div className="menu" ref={wrapperRef}> <p>Menu</p> </div> ) ); } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
Consultez cette bibliothèque sur Andarist appelée use-onclickoutside .
import * as React from 'react' import useOnClickOutside from 'use-onclickoutside' export default function Modal({ close }) { const ref = React.useRef(null) useOnClickOutside(ref, close) return <div ref={ref}>{'Modal content'}</div> }
Une autre solution consiste à utiliser une boîte invisible plein écran.
.Menu{ z-index: 1; } .Invisible{ height: 100vh; left: 0; position: fixed; top: 0; width: 100vw; z-index: 0; }
Et le CSS:
import React, { useState } from 'react'; const Menu = () => { const [active, setActive] = useState(false); return( <div> {/* The menu has z-index = 1, so it's always on top */} <div className = 'Menu' onClick = {() => setActive(true)} {active ? <p> Menu active </p> : <p> Menu inactive </p> } </div> {/* This is a full-screen box with z-index = 0 */} {active ? <div className = 'Invisible' onClick = {() => setActive(false)}></div> : null } </div> ); }
Vous devriez probablement lire ceci a > et ceci , et ceci ... puis reconsidérez votre question.
Jetez un oeil à ma réponse de pile incl. exemple de travail avec les hooks de réaction et la détection des clics extérieurs ici: stackoverflow.com/questions/32553158/... . Cela vous aide-t-il?