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

145
Views
¿Por qué se llama dos veces al controlador de eventos?

Estoy desarrollando una aplicación React JS que se supone que se ejecuta en dispositivos móviles.

Aquí están los extractos del código de la aplicación:

índice.tsx:

 import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; ReactDOM.render( <React.StrictMode> <App/> </React.StrictMode>, document.getElementById('root') );

Aplicación.tsx:

 import React from 'react'; import './App.css'; import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'; import {Header} from "./Components/header" import {Footer} from "./Components/footer" import {Sidebar} from "./Components/sidebar" //... const listener = () => { console.log("Main listener") }; function App() { const media = window.matchMedia('(min-width: 700px)'); media.addEventListener("change", listener); return ( <Router> <div className="App"> <Header /> <Sidebar /> <Footer /> //... </div> </Router> ); } export default App;

¡El problema es que la función del controlador de eventos de change ( listener ) se llama DOS VECES! cuando cambio el tamaño de la ventana del navegador. He leído que investigué que el motivo es la etiqueta React Strict Mode . Como dice el documento oficial , el Strict Mode hace una doble invocación de las siguientes funciones:

  • Constructor de componentes de clase, renderizar y métodos shouldComponentUpdate

  • Componente de clase método estático getDerivedStateFromProps

  • Cuerpos de componentes de función

  • Funciones de actualización de estado (el primer argumento de setState)

  • Funciones pasadas a useState, useMemo o useReducer

Mi pregunta es ¿POR QUÉ el evento vinculado se llama DOS VECES ya que el documento no enumera los controladores de eventos como invocados dos veces?

¿Es ese contexto LO QUE finalmente hace que el evento de change se invoque dos veces?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Este es el StrictMode de React que le llama la atención de manera proactiva sobre un error. No debe suscribirse a eventos en el nivel superior de una función de componente, porque se llama cada vez que se procesa el componente, por lo que cada vez que agrega una nueva suscripción al evento. Cuando tiene varias suscripciones a un evento (en diferentes objetos de origen de eventos), recibe varias devoluciones de llamada a su devolución de llamada de evento (una para cada suscripción).

En su lugar, suscríbase una vez en una devolución de llamada de useEffect con una matriz de dependencias vacía (y anule la suscripción de una devolución de llamada de limpieza que devuelve), detalles aquí .

 function App() { // An effect only called once on mount (empty deps array) useEffect(() => { // Subscribe once const media = window.matchMedia("(min-width: 700px)"); media.addEventListener("change", listener); // Unsubscribe on unmount return () => { media.removeEventListener("change", listener); }; }, []); // ... }

En un comentario has preguntado:

... ¿Pueden explicarme POR QUÉ la siguiente suscripción a eventos múltiples no es explícita?

 media.addEventListener("change", listener); media.addEventListener("change", listener)

Porque en ese código, está llamando a addEventListener dos veces en la misma MediaQueryList y pasando el mismo controlador de eventos ( listener ). Si agrega el mismo oyente para el mismo evento al mismo objeto dos veces, la segunda vez se ignora (por el sistema de eventos DOM; diferentes sistemas lo manejan de manera diferente).

Pero eso no es lo que está haciendo su componente. La función de su componente se ejecuta más de una vez, y cada vez crea una nueva MediaQueryList y le agrega un controlador, como este:

 const listener = () => { console.log("listener fired"); }; const YourComponent = () => { const media = window.matchMedia("(min-width: 700px)"); media.addEventListener("change", listener); }; YourComponent(); YourComponent();

O para decirlo aún más claramente:

 const media1 = window.matchMedia("(min-width: 700px)"); media1.addEventListener("change", listener); const media2 = window.matchMedia("(min-width: 700px)"); media2.addEventListener("change", listener);

Dado que son objetos MediaQueryList diferentes, el oyente se agrega cada vez (una vez a cada objeto).

Si ejecuta ese fragmento, cambie el tamaño de su navegador para que el oyente se dispare, verá que se dispara dos veces.

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!