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

126
Views
Los eventos externos de React 2 no pueden compartir datos de enlace

Tengo 2 eventos externos, input y keydown para un elemento de entrada, cuando se activa la entrada, llamará a setInput en el componente React. Cuando se dispara el evento keydown para arrowDown , idealmente el valor de entrada debería ser el establecido dentro de handleInput , pero está vacío, ¿me pierdo algo?

 const SearchBox : React.FunctionComponent<ISearchProps> = React.memo((props: ISearchProps) => { const [input, setInput] = React.useState({value: '', redirect: false}); useEffect(() => { const container = document.querySelector('.xxx'); container.addEventListener('input', handleInput); container.addEventListener('keydown', handleKeyboardEvent); }, []); const handleInput = (e) => { setInput({value: e.currentTarget.value, redirect: false}); } const handleKeyboardEvent = (e) => { switch (e.key) { case 'ArrowDown': console.log(input); setActiveSuggestionIndex(activeSuggestionIndex === suggestions.length - 1 ? 0 : activeSuggestionIndex + 1); e.preventDefault(); break; default: break; } } }
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Tema

Este es un problema de recintos de estado obsoletos en una función de devolución de llamada. El valor de estado de input inicial de { value: '', redirect: false } se cierra en la copia de handleKeyboardEvent del ciclo de procesamiento inicial. Nunca se actualizará.

Soluciones

Use React ref y useEffect para almacenar en caché una copia del valor

Use una referencia React y un useEffect adicional para almacenar en caché un valor al que se accederá de forma asíncrona en la devolución de llamada.

 const [input, setInput] = React.useState({ value: '', redirect: false }); const inputRef = React.useRef(input); // <-- state cache useEffect(() => { const container = document.querySelector('.xxx'); container.addEventListener('input', handleInput); container.addEventListener('keydown', handleKeyboardEvent); return () => { container.removeEventListener('input', handleInput); container.removeEventListener('keydown', handleKeyboardEvent); }; }, []); useEffect(() => { inputRef.current = input; // <-- update state cache value }, [input]); const handleInput = (e) => { setInput({ value: e.currentTarget.value, redirect: false }); }; const handleKeyboardEvent = (e) => { switch (e.key) { case 'ArrowDown': console.log(inputRef); // <-- read current state cache value setActiveSuggestionIndex(activeSuggestionIndex => activeSuggestionIndex === suggestions.length - 1 ? 0 : activeSuggestionIndex + 1 ); e.preventDefault(); break; default: break; } };

Use useEffect con función de dependencia y limpieza

Dado que también debería devolver una función de limpieza de useEffect para eliminar los detectores de eventos al desmontar, agregue el estado de input a la matriz de dependencia ( y cualquier otra dependencia faltante de la que se pueda quejar el linter ) para que cuando el estado de input se actualice, el el valor del estado actual se vuelve a encerrar en el alcance de devolución de llamada.

 useEffect(() => { const handleInput = (e) => { setInput({ value: e.currentTarget.value, redirect: false }); }; const handleKeyboardEvent = (e) => { switch (e.key) { case 'ArrowDown': console.log(input); setActiveSuggestionIndex(activeSuggestionIndex => activeSuggestionIndex === suggestions.length - 1 ? 0 : activeSuggestionIndex + 1 ); e.preventDefault(); break; default: break; } }; const container = document.querySelector('.xxx'); container.addEventListener('input', handleInput); container.addEventListener('keydown', handleKeyboardEvent); return () => { container.removeEventListener('input', handleInput); container.removeEventListener('keydown', handleKeyboardEvent); }; }, [input]);
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!