Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

110
Visualizações
¿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 Respostas
Responde à pergunta

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 Relatório

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 registros es una elección de diseño realmente mala .

over 4 years ago · Santiago Trujillo Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda