es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cuántas veces debe renderizarse React?

Escribí un simple React para probar cómo renderiza React.

import ReactDOM from 'react-dom';
import React, { useState, useEffect } from 'react';

const App = (props) => {
  // State
  const [trackIndex, setTrackIndex] = useState(1);
  const [trackProgress, setTrackProgress] = useState(0);
  const clickHandler = () =>{
       setTrackIndex((trackIndex)=>trackIndex+1)
  }

  useEffect(() => {
    console.log("effect; trackIndex=",trackIndex)
    console.log("effect; trackProgress=",trackProgress)
    if(trackIndex<5){
      console.log("set trackProgress")
      setTrackProgress(trackIndex)
    }
  });

  console.log("render")

  return (
    <div>
      <p>{trackIndex}</p>
      <p>{trackProgress}</p>
      <button onclick="{clickHandler}">Click me</button>
    </div>
  );
};

ReactDOM.render(
  <app></app>,
document.getElementById('root')
);

El siguiente es el resultado en la consola:

render
effect; trackIndex= 1
effect; trackProgress= 0
set trackProgress
render
effect; trackIndex= 1
effect; trackProgress= 1
set trackProgress
render

Parece que React renderiza tres veces antes de que haga click en el botón. La última renderización realmente me confunde. ¿Podría alguien explicarme por qué se produce esta renderización y por qué no se ejecuta ningún efecto después de esta renderización? Gracias de antemano.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El primer renderizado ocurre cuando ReactDOM renderiza el componente App por primera vez. El segundo renderizado ocurre cuando la variable de estado trackIndex se actualiza mediante la función clickHandler, lo que provoca que el componente se vuelva a renderizar. El tercer renderizado ocurre porque al cambiar la variable de estado trackProgress en el hook useEffect se produce un nuevo renderizado.

    En cuanto al último renderizado, podría ser causado por varias razones. Es posible que alguna otra variable de estado se esté cambiando en otro lugar del código, lo que provoca otro renderizado. También podría ser causado por algún componente padre que se renderiza y pasa nuevas props al componente App.

    En cuanto al hook de efecto que no se ejecuta después del último renderizado, es probable que se deba a que la lista de dependencias no se ha actualizado. Cuando se ejecuta el hook de efecto, se está observando la variable de estado trackIndex, pero como esa variable no cambió en el último renderizado, el hook de efecto no se ejecuta.

    Para solucionarlo, se podría añadir una lista vacía como segundo argumento al hook useEffect para que se ejecute solo una vez en el montaje, de esta manera:

    useEffect(() => {
      console.log("effect; trackIndex=", trackIndex)
      console.log("effect; trackProgress=", trackProgress)
      if (trackIndex < 5) {
        console.log("set trackProgress")
        setTrackProgress(trackIndex)
      }
    }, []); // añadir lista vacía aquí
    

    Esto haría que el hook de efecto se ejecute solo una vez cuando se monta el componente, y no se vuelva a ejecutar durante los siguientes renderizados.

Comments are closed.