Estoy tratando de configurar un menú contextual personalizado, sin embargo, cada vez que el usuario hace clic derecho, la función del menú contextual devuelve 6 veces separadas, la quinta es lo que necesito y la sexta son los valores de estado predeterminados. Sin embargo, si el usuario hace doble clic derecho en el mismo lugar, regresa 5 veces, siendo el quinto retorno los valores deseados y se abre el menú. ¿Hay alguna manera de verificar antes de la devolución si todos los estados han cambiado y solo regresar de la devolución de llamada si toda la información necesaria está presente?
const ContextMenu = outerRef => { const [xPos, setXPos] = useState("0px"); const [yPos, setYPos] = useState("0px"); const [menu, showMenu] = useState(false); const [menuTarget, setMenuTarget] = useState(''); const [menuTargetId, setMenuTargetId] = useState(''); const handleContextMenu = useCallback( event => { if(event.target.className && (event.target.className.includes('bar') ||event.target.className == 'timeline' || event.target.className == 'draggablediv' || event.target.className == 'editableDiv')){ event.preventDefault(); if (outerRef && outerRef.current.contains(event.target)) { setXPos(`${event.pageX}px`); setYPos(`${event.pageY}px`); setMenuTarget(event.target.className) setMenuTargetId(event.target.id) showMenu(true); } else { showMenu(false); } } },[showMenu, outerRef, setXPos, setYPos]); const handleClick = useCallback(() => { showMenu(false); }, [showMenu]); useEffect(() => { document.addEventListener("click", handleClick); document.addEventListener("contextmenu", handleContextMenu); return () => { document.removeEventListener("click", handleClick); document.removeEventListener("contextmenu", handleContextMenu); }; }, []); return {xPos, yPos, menu, menuTarget, menuTargetId}; };useCallback acepta una función que devuelve el valor memorizado. Como useCallback(() => 5, []) , o en su caso useCallback(() => event => {...}, []) .
Esto se debe a que React tiene que llamar a la función para obtener el valor para memorizar, por lo que se llama a sus configuradores en cada renderizado. Que es lo que está causando toda la rareza.
Sin embargo, incluso con esa solución, no creo que sea correcto usar una función que cambie las referencias en addEventListener. Nunca tendrá valores actualizados en su controlador de menú contextual porque se referirá a una versión anterior de handleContextMenu. Probablemente tendrá que usar una forma más idiomática de adjuntar una función a un evento de interfaz de usuario que la API del documento global.