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

213
Views
¿Por qué `Promise.then` se llama dos veces en un componente React pero no en console.log?

Estoy muy confundido acerca de la salida del siguiente componente:

 import { StrictMode } from "react" import ReactDOM from "react-dom" function Test(): React.ReactElement { console.log('render') Promise.resolve() .then(() => console.log('then ' + Math.random())) return <></> } ReactDOM.render( <StrictMode> <Test /> </StrictMode>, document.getElementById("root") )

Produce el siguiente resultado al menos en Chrome y Firefox:

 00:46:30.264 render 00:46:30.267 then 0.5430663800781927 00:46:30.267 then 0.9667426372511254

Prefiero esperar ver el mismo número de mensajes. ¿Qué me estoy perdiendo?

Reproducción: https://codesandbox.io/s/elegant-frost-dmcsl

EDITAR: sé que el modo estricto conduce a una representación adicional, pero como se indicó, esperaría el mismo recuento de mensajes.

EDIT 2: Ambas respuestas a continuación son geniales. Me gustaría citar el comentario de @user56reinstatemonica8 aquí:

Relevante: comentarios de la comunidad sobre el silenciamiento de la consola

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

En el modo estricto de Reacción, la reacción puede ejecutar el procesamiento varias veces, lo que podría explicar en parte lo que ve.

Pero se preguntó correctamente si ese era el caso y el renderizado se llamó varias veces, ¿por qué el render no se imprimió dos veces también ?

React modifica los métodos de la consola como console.log() para silenciar los registros en algunos casos. Aquí hay una cita:

A partir de React 17, React modifica automáticamente los métodos de la consola como console.log() para silenciar los registros en la segunda llamada a las funciones del ciclo de vida. Sin embargo, puede causar un comportamiento no deseado en ciertos casos en los que se puede utilizar una solución alternativa.

Aparentemente, no lo hace cuando se llama a console.log desde la devolución de llamada de Promise. Pero lo hace cuando se llama desde render. Más detalles sobre esto están en la respuesta de @trincot.

over 4 years ago · Santiago Trujillo Report

0

Hay una segunda ejecución de su función de procesamiento cuando el modo estricto está habilitado (solo en el modo de desarrollo), pero como se explica aquí , React usará los métodos de la console parches (llamando a disableLogs(); ) durante la duración de esa segunda ejecución (sincrónica), para que no salga.

El registro de cambios muestra que este código se insertó en packages/react-reconciler/src/ReactFiberBeginWork.js para suprimir temporalmente los registros (inserciones marcadas con comentarios):

 if (__DEV__) { ReactCurrentOwner.current = workInProgress; setIsRendering(true); nextChildren = renderWithHooks( current, workInProgress, render, nextProps, ref, renderExpirationTime, ); if ( debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode ) { disableLogs(); // <-- try { // <-- nextChildren = renderWithHooks( current, workInProgress, render, nextProps, ref, renderExpirationTime, ); } finally { // <-- reenableLogs(); // <-- } // <--

Aquí hay una versión de su código que demuestra que realmente se ejecuta dos veces:

 var i = 0; var myconsolelog = console.log; // Work around React's monkeypatching function Test(): React.ReactElement { i++; myconsolelog(i + ". render"); // will output twice now! Promise.resolve(i) .then((i) => console.log(i + ". then " + Math.random())); return <></>; }

En mi opinión, esta supresión de registro es una elección de diseño realmente mala .

over 4 years ago · Santiago Trujillo Report

0

En caso de que pueda ayudar a alguien, puede aplicar un parche de mono a Object.defineProperties para ignorar cualquier cambio realizado en el objeto de la console , evitando efectivamente que ReactDOM aplique un parche de mono a console.log .

 const defineProperties = Object.defineProperties; Object.defineProperties = function (o, props) { return o === console ? o : defineProperties(o, props); };

Asegúrese de poner esto solo en modo de desarrollo (por ejemplo, en create-react-app cuando process.env.NODE_ENV === 'development' ), para que no termine en la compilación de producción.

over 4 years ago · Santiago Trujillo 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!