Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

187
Views
mouseEnter y mouseLeave funcionan en elementos HTML, pero no en componentes React?

Primera vez haciendo un sitio React (usando Gatsby).

lo que quiero que pase

En mi página de índice, estoy tratando de hacer que aparezca un componente Note cuando el mouse pasa sobre un componente Term .

que esta pasando

Cuando agrego onMouseEnter y onMouseLeave directamente al componente Term , la Note nunca aparece. Sin embargo, si uso un elemento html nativo ( span en el código de ejemplo a continuación) en lugar de <Term/> , aparece la Note .

¿Tiene algo que ver con la función de flecha?

  • Reemplazar () => setShowNoteB(true) con console.log("in TermB") (más o menos) funciona.
  • Pero usar onMouseEnter={setShowNoteB(true)} da como resultado un error de bucle infinito.

¿Está relacionado con cómo estoy componiendo los componentes? ¿O es una limitación del gancho useState ? Lo que estoy haciendo aquí parece bastante simple/directo, pero nuevamente, soy nuevo en esto, así que tal vez haya alguna regla que desconozco.

Código de ejemplo

Página de inicio

 //index.js import * as React from 'react'; import { useState } from 'react'; import Term from '../components/term'; import Note from '../components/note'; const IndexPage = () => { const [showNoteA, setShowNoteA] = useState(false); const [showNoteB, setShowNoteB] = useState(false); return ( <> <h1 > <span onMouseEnter={() => setShowNoteA(true)} onMouseLeave={() => setShowNoteA(false)} > TermA* </span> {" "} doesn't behave like {" "} <Term word="TermB" symbol="†" onMouseEnter={() => setShowNoteB(true)} onMouseLeave={() => setShowNoteB(false)} /> </h1> {showNoteA ? <Note> <p>This is a note for TermA.</p> </Note> : null} {showNoteB ? <Note> <p>This is a note for TermB.</p> </Note> : null} </> ); }; export default IndexPage

Componente de término

 // term.js import React from 'react'; const Term = ({ word, symbol }) => { return ( <div> <span>{word}</span> <span>{symbol}</span> </div> ); }; export default Term;

Componente de nota

 // note.js import * as React from 'react'; const Note = ({ children })=> { return ( <div> {children} </div> ) }; export default Note;
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Solución con useEffect , useRef , forwardRef y addEventListener/removeEventListener :

Aplicación.js

 import React, { useRef } from 'react'; import Term from './Term'; export default function App() { const ref = useRef({}); return ( <div> Lorem ipsum dolor sit amet,{' '} <Term ref={ref} word="consectetur" symbol="†" /> adipiscing elit. Morbi laoreet <Term ref={ref} word="lacus" /> in dui vestibulum, nec imperdiet augue vulputate. </div> ); }

Si desea agregar otros términos, simplemente cree un nuevo componente Término y agregue los accesorios ref , word , symbol (opcional).

Term.js

 import React, { useState, useEffect, forwardRef } from 'react'; import Note from './Note'; function Term({ word, symbol }, ref) { const [isHovered, setHovered] = useState(false); const [currentTerm, setCurrentTerm] = useState(''); const [currentSymbol, setCurrentSymbol] = useState(''); useEffect(() => { if (ref.current && word) { ref.current[word].addEventListener('mouseover', handleMouseover); ref.current[word].addEventListener('mouseout', handleMouseout); return () => { ref.current[word].removeEventListener('mouseover', handleMouseover); ref.current[word].removeEventListener('mouseout', handleMouseout); }; } }, [ref.current, word]); const handleMouseover = () => { setHovered(true); setCurrentTerm(word); setCurrentSymbol(symbol); }; const handleMouseout = () => { setHovered(false); setCurrentTerm(''); setCurrentSymbol(''); }; return ( <> <span ref={(elem) => (ref.current[word] = elem)}> {word} </span> {isHovered ? <Note word={currentTerm} symbol={currentSymbol} /> : null} </> ); } const forwarded = forwardRef(Term); export default forwarded;

nota.js

 import React from 'react'; export default function Note({ word, symbol }) { const checkTerm = (term) => { switch (term) { case 'consectetur': return `definition`; case 'lacus': return `definition`; default: return null; } }; return ( <div> <p> {word} {symbol ? symbol : '-'} </p> <p>{checkTerm(word)}</p> </div> ); }

Demostración: Stackblitz

about 4 years ago · Juan Pablo Isaza Report

0

Cuando usa Componentes en su JSX, a diferencia de las etiquetas HTML (en minúsculas), cualquier atributo solo se pasa como accesorio y no tiene ningún efecto directo.

 <Term word="TermB" symbol="†" onMouseEnter={() => setShowNoteB(true)} onMouseLeave={() => setShowNoteB(false)} />

Debe tomar el apoyo pasado y asignarlo a un elemento HTML real en el JSX del componente, así:

 const Term = ({ word, symbol, onMouseEnter, onMouseLeave }) => { return ( <div onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}> <span>{word}</span> <span>{symbol}</span> </div> ); };
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!