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?