{"id":29905,"date":"2024-10-08T15:47:04","date_gmt":"2024-10-08T13:47:04","guid":{"rendered":"https:\/\/www.codemotion.com\/magazine\/?p=29905"},"modified":"2024-10-08T15:47:05","modified_gmt":"2024-10-08T13:47:05","slug":"como-funciona-el-renderizado-en-react","status":"publish","type":"post","link":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/","title":{"rendered":"\u00bfC\u00f3mo funciona el renderizado en React?"},"content":{"rendered":"\n<p>React es una de las librer\u00edas de c\u00f3digo abierto m\u00e1s conocidas para la construcci\u00f3n de UI y est\u00e1 basada en principios de programaci\u00f3n funcional y reactiva:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Los componentes est\u00e1n declarados como funciones puras que reciben propiedades como argumento y devuelven elementos de React (que pueden ser elementos del DOM, <code>string<\/code>, <code>number<\/code>, <code>boolean<\/code> e incluso <code>null<\/code> o <code>undefined<\/code> si no queremos \u201cpintar\u201d nada).<\/li>\n\n\n\n<li>Como su propio nombre indica, una de las ventajas de los componentes es que se pueden componer, construyendo componentes m\u00e1s grandes a partir de otros m\u00e1s peque\u00f1os.<\/li>\n\n\n\n<li>Se promueve el uso de estructuras de datos inmutables. No se modifica directamente el estado, si no que se crea una nueva versi\u00f3n del estado que incluye los cambios necesarios.<\/li>\n\n\n\n<li>Los componentes reaccionan a los cambios de estado, volvi\u00e9ndose a renderizar de forma eficiente para aplicar estos cambios.<\/li>\n\n\n\n<li>La ejecuci\u00f3n de efectos colaterales se produce dentro del hook <code>useEffect<\/code>, lo que asegura que estos tambi\u00e9n responder\u00e1n a los cambios de estado.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-que-significa-que-un-componente-se-renderiza\">\u00bfQu\u00e9 significa que un componente se renderiza?<\/h2>\n\n\n\n<p>React funciona con el llamado Virtual DOM, que no es m\u00e1s que una representaci\u00f3n del DOM en memoria.<\/p>\n\n\n\n<p>Cuando detecta un cambio, construye el nuevo Virtual DOM y lo compara con el anterior en el proceso llamado diferenciaci\u00f3n (o d<em>iffing<\/em>).<\/p>\n\n\n\n<p>Una vez que React ha determinado qu\u00e9 partes del Virtual DOM real han cambiado, si es necesario, aplica las actualizaciones necesarias sobre el DOM real, pudiendo agrupar m\u00faltiples actualizaciones en la misma operaci\u00f3n (batching).<\/p>\n\n\n\n<p>Hay que remarcar que incluso cuando el DOM real no cambia, esta comparaci\u00f3n entre estados del Virtual DOM consumir\u00e1 recursos.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-cuando-se-renderiza-un-componente-en-react\">\u00bfCuando se renderiza un componente en React?<\/h2>\n\n\n\n<p>Por defecto, un componente se renderiza:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cuando la aplicaci\u00f3n se inicia<\/h3>\n\n\n\n<p>Cuando llamamos a <code>createRoot<\/code> y luego al m\u00e9todo <code>render<\/code> en el objeto devuelto o bien cuando usamos un framework como Next que se encarga de construir la estructura inicial de la p\u00e1gina y convertirla a c\u00f3digo HTML que posteriormente se devuelve como respuesta.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Cuando se produce un cambio en el estado<\/h3>\n\n\n\n<p>En React el estado se gestiona mediante el uso de los hooks <code>useState<\/code>, <code>useReducer<\/code> o <code>useSyncWithExternalStore<\/code>.<\/p>\n\n\n\n<p>En el caso m\u00e1s sencillo (<code>useState<\/code>) el hook devuelve una tupla donde la primera posici\u00f3n es el valor actual de ese estado y la segunda posici\u00f3n es un dispatcher (<em>updater)<\/em> que nos permite actualizar el valor de ese estado de tal forma que el \u00e1rbol de componentes transforme ese cambio de estado en un cambio en la UI.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1665\" height=\"401\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_01.png\" alt=\"\" class=\"wp-image-29954\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_01.png 1665w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_01-300x72.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_01-1024x247.png 1024w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_01-768x185.png 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_01-1536x370.png 1536w\" sizes=\"auto, (max-width: 1665px) 100vw, 1665px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Un cambio de estado en el padre siempre se propaga a los hijos<\/h3>\n\n\n\n<p>Un componente siempre se re-renderizar\u00e1 cuando se modifique su estado interno.<\/p>\n\n\n\n<p>En el caso de un componente compuesto, que se encargue de invocar a otros subcomponentes, es importante rese\u00f1ar que, por defecto, <strong>estos subcomponentes siempre se re-renderizar\u00e1n cuando el estado del componente padre cambie<\/strong>, aun cuando las props recibidas no cambien o cuando no dependan de ninguna prop.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"389\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_02-1024x389.png\" alt=\"\" class=\"wp-image-29956\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_02-1024x389.png 1024w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_02-300x114.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_02-768x292.png 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_02-1536x584.png 1536w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_02.png 1665w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/**\n * En este ejemplo, Intro, Wargning y Label se re-renderizar\u00edan\n * cuando cambie \"counter\"\n *\/<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> MyComponent = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> &#91;counter, setCounter] = useState(<span class=\"hljs-number\">0<\/span>);\n\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Intro<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Warning<\/span> <span class=\"hljs-attr\">isGt10<\/span>=<span class=\"hljs-string\">{counter<\/span> &gt;<\/span> 10} \/&gt;\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setCounter(prev =&gt; prev + 1)}&gt;\n        Increment\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Label<\/span> <span class=\"hljs-attr\">counter<\/span>=<span class=\"hljs-string\">{counter}<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setCounter(prev =&gt; prev - 1)}&gt;\n        Decrement\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n  )\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-strict-mode\">Strict mode<\/h2>\n\n\n\n<p>Hay que mencionar que cuando trabajamos con el <a href=\"https:\/\/es.react.dev\/reference\/react\/StrictMode\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">modo estricto activo en React<\/a> nuestros componentes y efectos se ejecutan por partida doble. Habr\u00e1 que tener esto en cuenta a la hora de hacer nuestras pruebas y comparar resultados, bien desactiv\u00e1ndolo o bien contando con esta ejecuci\u00f3n doble.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">memo<\/h2>\n\n\n\n<p>Mediante el uso de la utilidad memo podemos memoizar un componente, de tal forma que solo reaccione a cambios en las props que recibe, aun cuando el estado interno de su padre cambie.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> { memo } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n\ninterface Props {\n  <span class=\"hljs-attr\">isGt10<\/span>: boolean;\n}\n\n<span class=\"hljs-keyword\">const<\/span> Warning = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ isGt10 }: Props<\/span>) =&gt;<\/span> isGt10 &amp;&amp; (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"warning\"<\/span>&gt;<\/span>Es mayor que 10<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n);\n\n<span class=\"hljs-keyword\">const<\/span> MemoizedWarning = memo(Warning);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Ahora, <code>MemoizedWarning<\/code> solo se re-renderizar\u00eda si cambia <code>isGt10<\/code> (siempre que no se le pasen otras props no declaradas).<\/p>\n\n\n\n<p>La utilidad <strong>memo<\/strong> permite un segundo par\u00e1metro opcional, que permite definir de qu\u00e9 forma se comparar\u00e1n las props anteriores con las nuevas a la hora de evaluar si el componente debe re-renderizarse. Sin embargo, siempre deber\u00edamos primar el enviar solo la informaci\u00f3n imprescindible a nuestro componente.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> { memo } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'react'<\/span>;\n\ninterface Props {\n  <span class=\"hljs-attr\">counter<\/span>: number;\n}\n\n<span class=\"hljs-keyword\">const<\/span> Warning = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ counter }: Props<\/span>) =&gt;<\/span> counter &gt; <span class=\"hljs-number\">10<\/span> &amp;&amp; (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"warning\"<\/span>&gt;<\/span>Es mayor que 10<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n);\n\n<span class=\"hljs-keyword\">const<\/span> MemoizedWarning = memo(Warning, (oldProps, newProps) =&gt; {\n  <span class=\"hljs-keyword\">const<\/span> oldCounterIsGt10 = oldProps.counter &gt; <span class=\"hljs-number\">10<\/span>;\n  <span class=\"hljs-keyword\">const<\/span> newCounterIsGt10 = newProps.counter &gt; <span class=\"hljs-number\">10<\/span>;\n  <span class=\"hljs-keyword\">return<\/span> oldCounterIsGt10 !== newCounterIsGt10;\n});<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Aunque este c\u00f3digo ser\u00eda perfectamente funcional, por un lado estar\u00eda otorgando la responsabilidad de definir si el warning se debe mostrar o no al propio componente, dificultando su posterior reutilizaci\u00f3n, y adem\u00e1s la evaluaci\u00f3n siempre ser\u00e1 m\u00e1s lenta que comparar simplemente con el operador de igualdad, que es la comparaci\u00f3n por defecto.<\/p>\n\n\n\n<p>Sin embargo, en algunas ocasiones nos podemos encontrar componentes complejos con problemas de performance donde la introducci\u00f3n de esta funci\u00f3n de comparaci\u00f3n personalizada nos puede ayudar a corregirlos. En cualquier caso, debemos ser cuidadosos, ya que estamos modificando el comportamiento normal del componente y esto nos puede introducir problemas en forma de componentes desactualizados.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfA qu\u00e9 llamamos \u201ccomponente hijo\u201d?<\/h2>\n\n\n\n<p>Hemos hecho menci\u00f3n a los componentes hijo en diferentes ocasiones, y esto puede causar confusi\u00f3n con la prop <code>children<\/code>, que es la convenci\u00f3n que tiene React para pasar un componente anidado.<\/p>\n\n\n\n<p>Por simplicidad, cuando hagamos menci\u00f3n a \u201cComponentes padre\u201d nos referiremos a aquellos responsables de renderizar a los \u201cComponentes hijo\u201d. Veamos el siguiente caso:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">interface Level2AProps {\n  <span class=\"hljs-attr\">children<\/span>: ReactNode;\n}\n\n<span class=\"hljs-keyword\">const<\/span> Level2A = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ children }: Level2AProps<\/span>) =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> &#91;counter, setCounter] = useState(<span class=\"hljs-number\">0<\/span>);\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      {children}\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Warning<\/span> <span class=\"hljs-attr\">isEnabled<\/span>=<span class=\"hljs-string\">{counter<\/span> &gt;<\/span>= 10}&gt;Has llegado al l\u00edmite<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Warning<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setCounter(prev =&gt; prev + 1)}&gt;\n        Increment\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Label<\/span> <span class=\"hljs-attr\">counter<\/span>=<span class=\"hljs-string\">{counter}<\/span> \/&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{()<\/span> =&gt;<\/span> setCounter(prev =&gt; prev - 1)}&gt;\n        Decrement\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span> \n  )\n}\n\n<span class=\"hljs-keyword\">const<\/span> Level2B = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span>&gt;<\/span>Este componente no se re-renderizar\u00e1<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span><\/span>\n)\n\n<span class=\"hljs-keyword\">const<\/span> Level1 = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Level2A<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Level2B<\/span> \/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Level2A<\/span>&gt;<\/span><\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li><code>Level1<\/code> es el responsable de renderizar <code>Level2A<\/code> y <code>Level2B<\/code> (usando el patr\u00f3n llamado \u201ccomposici\u00f3n de contenido\u201d o \u201ccontent composition pattern\u201d).<\/li>\n\n\n\n<li><code>Level1<\/code> no tiene estado interno, por lo que, a menos que se vea afectado por el responsable de renderizarlo, no va a cambiar.<\/li>\n\n\n\n<li>Al no cambiar <code>Level1<\/code>, no propagar\u00e1 ese cambio a <code>Level2A<\/code> y <code>Level2B<\/code>.<\/li>\n\n\n\n<li><code>Level2A<\/code> s\u00ed que tiene un estado interno. Si este estado cambia, todos los componentes de cuya renderizaci\u00f3n es responsable se actualizar\u00e1n.<\/li>\n\n\n\n<li><code>Level2A<\/code> no es el responsable de renderizar <code>Level2B<\/code>, sino que recibe un valor a trav\u00e9s de la prop <code>children<\/code>.<\/li>\n\n\n\n<li>Con todo lo anteriormente descrito podemos deducir que ni <code>Level1<\/code> ni <code>Level2B<\/code> se re-renderizar\u00edan cuando se modificara el estado de <code>counter<\/code> en el componente <code>Level2A<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\u00bfCu\u00e1ndo y por qu\u00e9 evitar re-renderizaciones innecesarias?<\/h2>\n\n\n\n<p>Comencemos por lo m\u00e1s simple: cu\u00e1ndo no merece la pena preocuparse por las re-renderizaciones.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/**\n * En casos como este, aplicar un memo no merece la pena\n *\/<\/span>\n\ninterface Props {\n  <span class=\"hljs-attr\">headerContent<\/span>: ReactNode;\n  mainContent: ReactNode;\n}\n\n<span class=\"hljs-keyword\">const<\/span> MyLayout = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ headerContent, mainContent }<\/span>) =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">header<\/span>&gt;<\/span>{headerContent}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">header<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span>&gt;<\/span>{mainContent}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>El componente anterior es muy simple. Por lo tanto, es m\u00e1s costoso evitar este re-render que dejar que simplemente suceda.<\/p>\n\n\n\n<p>Sin embargo no todos los componentes son igual de livianos. Podemos encontrar:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Listados enormes, costosos de re-renderizar.<\/li>\n\n\n\n<li>Componentes que hacen uso de <code>useEffect<\/code> para comunicarse con librer\u00edas de terceros imperativamente, donde necesitamos asegurarnos que el componente no se actualiza de forma innecesaria.<\/li>\n\n\n\n<li>Componentes que contienen transiciones visuales que no queremos que se interrumpan.<\/li>\n<\/ul>\n\n\n\n<p>En cualquiera de estos casos, el conocimiento de las diferentes herramientas que React nos proporciona nos dotar\u00e1 de una mayor versatilidad a la hora de asegurarnos que nuestras aplicaciones son eficientes y resilientes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">useMemo<\/h2>\n\n\n\n<p>El hook <code>useMemo<\/code> sirve mayoritariamente para dos prop\u00f3sitos:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Evitar que un procesamiento costoso se vuelva a ejecutar de forma innecesaria si no ha cambiado ninguno de los datos de los que depende.<\/li>\n\n\n\n<li>Evitar generar una nueva referencia a la hora de realizar transformaciones que devuelvan arrays u objetos si no han cambiado sus dependencias (esto es especialmente \u00fatil si estamos pasando esa prop derivada a un componente envuelto con <code>memo<\/code> o si estamos usando este dato derivado en un <code>useEffect<\/code>).<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ \"computeExpensiveOperation\" solo se ejecuta si \"lines\" es diferente<\/span>\n<span class=\"hljs-comment\">\/\/ al renderizado anterior<\/span>\n<span class=\"hljs-keyword\">const<\/span> total = useMemo(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> computeExpensiveOperation(lines), &#91;lines]);\n\n<span class=\"hljs-comment\">\/\/ \"parsedOptions\" mantendr\u00eda su referencia siempre que \"options\" no cambie<\/span>\n<span class=\"hljs-keyword\">const<\/span> parsedOptions = useMemo(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> options.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ label, value }<\/span>) =&gt;<\/span> ({\n  label,\n  value\n})), &#91;options]);\n\nuseEffect(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  trackAnalytics(<span class=\"hljs-string\">'options_loaded'<\/span>, parsedOptions);\n}, &#91;parsedOptions]);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Para evitar inconsistencias, es importante que declaremos correctamente todas las dependencias que use. <a href=\"https:\/\/www.npmjs.com\/package\/eslint-config-react-app\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">La config oficial de React para eslint<\/a> nos puede ser de gran ayuda al avisarnos si estamos incumpliendo esta norma.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">useCallback<\/h2>\n\n\n\n<p>El hook <code>useCallback<\/code> es <em>az\u00facar sint\u00e1ctico<\/em> para mejorar la legibilidad a la hora de memoizar una funci\u00f3n.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> handleClick = useCallback(\n  <span class=\"hljs-function\">(<span class=\"hljs-params\">value: string<\/span>) =&gt;<\/span> {\n    performSearch(value);\n  },\n  &#91;performSearch],\n);\n\n<span class=\"hljs-comment\">\/\/ Con useMemo aunque posible y equivalente, es menos legible<\/span>\n<span class=\"hljs-keyword\">const<\/span> handleClick2 = useMemo(\n  <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> <span class=\"hljs-function\">(<span class=\"hljs-params\">value: string<\/span>) =&gt;<\/span> {\n    performSearch(value);\n  },\n  &#91;performSearch],\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>El objetivo de memoizar una funci\u00f3n es evitar la creaci\u00f3n de nuevas referencias entre renderizados del componente, lo cu\u00e1l puede ser \u00fatil si estamos pasando esta funci\u00f3n como prop a un componente hijo que est\u00e1 envuelto en <code>memo<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">const<\/span> &#91;items, setItems] = useState(initialItems);\n\n<span class=\"hljs-keyword\">const<\/span> completedItems = useMemo(\n  <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> items.filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ isComplete }<\/span>) =&gt;<\/span> isComplete),\n  &#91;items],\n);\n\n<span class=\"hljs-keyword\">const<\/span> handleConfirmCleaning = useCallback(\n  <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> setItems(<span class=\"hljs-function\"><span class=\"hljs-params\">prevItems<\/span> =&gt;<\/span> prevItems.filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">{ isComplete }<\/span>) =&gt;<\/span> isComplete),\n  &#91;],\n);\n\n<span class=\"hljs-keyword\">const<\/span> handleUnmarkItem = useCallback(\n  <span class=\"hljs-function\">(<span class=\"hljs-params\">id: number<\/span>) =&gt;<\/span> {\n    setItems(<span class=\"hljs-function\"><span class=\"hljs-params\">prevItems<\/span> =&gt;<\/span> prevItems.map(<span class=\"hljs-function\">(<span class=\"hljs-params\">prevItem<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">if<\/span> (prevItem.id !== id) {\n        <span class=\"hljs-keyword\">return<\/span> prevItem;\n      }\n      <span class=\"hljs-keyword\">return<\/span> {\n        ...prevItem,\n        <span class=\"hljs-attr\">isComplete<\/span>: <span class=\"hljs-literal\">false<\/span>,\n      };\n    }));\n  },\n  &#91;],\n);\n\n<span class=\"hljs-keyword\">return<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MemoizedExpensiveLayout<\/span> <span class=\"hljs-attr\">handleConfirmCleaning<\/span>=<span class=\"hljs-string\">{handleConfirmCleaning}<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">MemoizedExpensiveComponent<\/span>\n      <span class=\"hljs-attr\">completedItems<\/span>=<span class=\"hljs-string\">{completedItems}<\/span>\n      <span class=\"hljs-attr\">handleUnmarkItem<\/span>=<span class=\"hljs-string\">{handleUnmarkItem}<\/span>\n    \/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/span>&gt;<\/span><\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Context API<\/h2>\n\n\n\n<p>Como hemos visto anteriormente, siempre que un componente actualiza su estado interno, provoca un re-renderizado de todos los componentes hijo que no est\u00e9n envueltos con <code>memo<\/code> , sin importar si dependen de este estado o no.<\/p>\n\n\n\n<p>Esto nos lleva a una de las m\u00e1ximas de React: \u201cpon tu estado en el nivel m\u00e1s bajo que te sea posible\u201d.<\/p>\n\n\n\n<p>\u00bfY qu\u00e9 pasa cuando tenemos componentes que est\u00e1n en diferentes niveles de la jerarqu\u00eda y que necesitan acceder a un estado compartido?<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"622\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_03-1024x622.png\" alt=\"\" class=\"wp-image-29957\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_03-1024x622.png 1024w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_03-300x182.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_03-768x466.png 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_03-1536x933.png 1536w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_03.png 1671w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Por un lado nos vemos obligados a pasar la prop <code>items<\/code> entre componentes intermedios (esto es, que no utilizan la prop) y por otro lado todos los componentes se van a re-renderizar cuando <code>items<\/code> cambie (incluso si est\u00e1n envueltos con <code>memo<\/code>, puesto que dependen de <code>items<\/code> para pasarla al componente hijo).<\/p>\n\n\n\n<p>Y justo para estos casos los contextos (Context API) en React nos vienen genial: Nos permiten propagar cualquier dato hacia abajo sin que los componentes intermedios se vean afectados por las actualizaciones, solo aquellos que est\u00e9n expl\u00edcitamente suscritos.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"667\" src=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_04-1024x667.png\" alt=\"\" class=\"wp-image-29958\" srcset=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_04-1024x667.png 1024w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_04-300x196.png 300w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_04-768x501.png 768w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_04-1536x1001.png 1536w, https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/img_04.png 1671w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ Creamos el contexto \"ItemContext\", as\u00ed como un \"Provider\" que lo propagar\u00e1<\/span>\n<span class=\"hljs-comment\">\/\/ hacia abajo y un hook llamado \"useItemsState\" que nos permite obtenerlo<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> ItemsContext = createContext&lt;{\n  <span class=\"hljs-attr\">items<\/span>: Item&#91;];\n  addItem: <span class=\"hljs-function\">(<span class=\"hljs-params\">item: Item<\/span>) =&gt;<\/span> <span class=\"hljs-keyword\">void<\/span>;\n  resetItems: <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> <span class=\"hljs-keyword\">void<\/span>;\n} | <span class=\"hljs-literal\">undefined<\/span>&gt;(<span class=\"hljs-literal\">undefined<\/span>);\n\n<span class=\"hljs-keyword\">const<\/span> ItemsProvider = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ children }: { children: ReactNode }<\/span>) =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> &#91;items, setItems] = useState&lt;Item&#91;]&gt;(&#91;]);\n  <span class=\"hljs-keyword\">const<\/span> value = useMemo(<span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> ({\n    items,\n    <span class=\"hljs-attr\">addItem<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">item: Item<\/span>) =&gt;<\/span> {\n      setItems(<span class=\"hljs-function\"><span class=\"hljs-params\">prevItems<\/span> =&gt;<\/span> &#91;...prevItems, item]),\n    },\n    <span class=\"hljs-attr\">resetItems<\/span>: <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> setItems(&#91;]),\n  }), &#91;items]);\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ItemsContext.Provider<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">{value}<\/span>&gt;<\/span>{children}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ItemsContext.Provider<\/span>&gt;<\/span><\/span>;\n};\n\n<span class=\"hljs-keyword\">const<\/span> useItemsState = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> value = useContext(ItemsContext);\n  <span class=\"hljs-keyword\">if<\/span> (!value) {\n    <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Error<\/span>(<span class=\"hljs-string\">'useItemsContext must be used inside an ItemsProvider'<\/span>);\n  }\n  <span class=\"hljs-keyword\">return<\/span> value;\n};\n\n<span class=\"hljs-comment\">\/\/ Envolvemos todos los componentes que dependan de este contexto<\/span>\n\n<span class=\"hljs-keyword\">const<\/span> MyApp = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> (\n  <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ItemsProvider<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Layout<\/span> <span class=\"hljs-attr\">topBar<\/span>=<span class=\"hljs-string\">{<\/span>&lt;<span class=\"hljs-attr\">TopBar<\/span> \/&gt;<\/span>} sideBar={<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">SideBar<\/span> \/&gt;<\/span>}&gt;\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ItemList<\/span> \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Layout<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ItemsProvider<\/span>&gt;<\/span><\/span>\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Una vez creado el contexto y envueltos nuestros componentes con el Provider correspondiente, solo nos queda acceder a este contexto en los componentes que realmente lo necesiten:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-comment\">\/\/ Este componente podr\u00eda ser renderizado por \"SideBar\" por ejemplo:<\/span>\n<span class=\"hljs-keyword\">const<\/span> ResetButton = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> { resetItems } = useItemsState();\n  <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span> <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{resetItems}<\/span>&gt;<\/span>Reset Items<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span><\/span>\n};\n\n<span class=\"hljs-keyword\">const<\/span> ItemList = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n  <span class=\"hljs-keyword\">const<\/span> { items } = useItemsState();\n  <span class=\"hljs-keyword\">return<\/span> (\n    <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul<\/span>&gt;<\/span>\n      {items.map((item) =&gt; (\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">{item.id}<\/span>&gt;<\/span>{item.title}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">li<\/span>&gt;<\/span>\n      ))}\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">ul<\/span>&gt;<\/span><\/span>\n  );\n};<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>En este caso ResetButton se re-renderizar\u00eda cada vez que items cambie, a pesar de no necesitar esa prop (incluso aunque envolvi\u00e9ramos el componente con <code>memo<\/code>). Esto es as\u00ed porque no podemos suscribirnos a partes de un contexto, es todo o nada.<\/p>\n\n\n\n<p>En componentes simples esto no va a suponer ning\u00fan problema, pero en componentes complejos tendr\u00edamos diferentes alternativas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Crear contextos independientes para las funciones que actualizan el estado (que es lo que necesita <code>ResetButton<\/code>) y para el valor del estado (que es lo que necesita <code>ItemList<\/code>).<\/li>\n\n\n\n<li>Si estamos tratando con estados y\/o componentes realmente complejos, podr\u00edamos hacer uso de una librer\u00eda de gesti\u00f3n de estado (Jotai, Recoil, Zustand, Redux\u2026). Estas librer\u00edas no solo nos permiten suscribirnos a las funciones de actualizaci\u00f3n de forma independiente, si no que nos permiten crear estados derivados: Imaginemos que tenemos un componente complejo que solo se debe mostrar si hay alg\u00fan item. Podr\u00edamos crear un selector a partir del listado de items que devuelva un <code>boolean<\/code>, que es a lo que finalmente se suscribir\u00eda nuestro componente.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusi\u00f3n<\/h2>\n\n\n\n<p>Conocer c\u00f3mo funciona el ciclo de renderizado de React y las herramientas disponibles nos ser\u00e1 \u00fatil para evitar renderizaciones innecesarias en componentes costosos, a evitar que nuestros efectos se ejecuten por duplicado innecesariamente y a discriminar cu\u00e1ndo no merece la pena aplicar una t\u00e9cnica de memoizaci\u00f3n.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>React es una de las librer\u00edas de c\u00f3digo abierto m\u00e1s conocidas para la construcci\u00f3n de UI y est\u00e1 basada en principios de programaci\u00f3n funcional y reactiva: \u00bfQu\u00e9 significa que un componente se renderiza? React funciona con el llamado Virtual DOM, que no es m\u00e1s que una representaci\u00f3n del DOM en memoria. Cuando detecta un cambio,&#8230; <a class=\"more-link\" href=\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\">Read more<\/a><\/p>\n","protected":false},"author":254,"featured_media":29960,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","_uag_custom_page_level_css":"","_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[10632],"tags":[10747],"collections":[],"class_list":{"0":"post-29905","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-frontend-es","8":"tag-desarrollo-web","9":"entry"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>\u00bfC\u00f3mo funciona el renderizado en React? - Codemotion Magazine<\/title>\n<meta name=\"description\" content=\"Aprende en este art\u00edculo de Jos\u00e9 Manuel Lucas c\u00f3mo funciona el ciclo de renderizado en React y qu\u00e9 herramientas est\u00e1n disponibles.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u00bfC\u00f3mo funciona el renderizado en React?\" \/>\n<meta property=\"og:description\" content=\"Aprende en este art\u00edculo de Jos\u00e9 Manuel Lucas c\u00f3mo funciona el ciclo de renderizado en React y qu\u00e9 herramientas est\u00e1n disponibles.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\" \/>\n<meta property=\"og:site_name\" content=\"Codemotion Magazine\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Codemotion.Italy\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-10-08T13:47:04+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-08T13:47:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1707\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"jmlweb\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:site\" content=\"@CodemotionIT\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"jmlweb\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\"},\"author\":{\"name\":\"jmlweb\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/b38417c0c79c66c436a78f8b207c514a\"},\"headline\":\"\u00bfC\u00f3mo funciona el renderizado en React?\",\"datePublished\":\"2024-10-08T13:47:04+00:00\",\"dateModified\":\"2024-10-08T13:47:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\"},\"wordCount\":1677,\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg\",\"keywords\":[\"Desarrollo web\"],\"articleSection\":[\"Frontend\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\",\"name\":\"\u00bfC\u00f3mo funciona el renderizado en React? - Codemotion Magazine\",\"isPartOf\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg\",\"datePublished\":\"2024-10-08T13:47:04+00:00\",\"dateModified\":\"2024-10-08T13:47:05+00:00\",\"description\":\"Aprende en este art\u00edculo de Jos\u00e9 Manuel Lucas c\u00f3mo funciona el ciclo de renderizado en React y qu\u00e9 herramientas est\u00e1n disponibles.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg\",\"width\":2560,\"height\":1707},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Frontend\",\"item\":\"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"\u00bfC\u00f3mo funciona el renderizado en React?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#website\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"name\":\"Codemotion Magazine\",\"description\":\"We code the future. Together\",\"publisher\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#organization\",\"name\":\"Codemotion\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"contentUrl\":\"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png\",\"width\":225,\"height\":225,\"caption\":\"Codemotion\"},\"image\":{\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Codemotion.Italy\/\",\"https:\/\/x.com\/CodemotionIT\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/b38417c0c79c66c436a78f8b207c514a\",\"name\":\"jmlweb\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e9b818c4bcbc06b196d66cea92d9fe41bd5ccd255dd3943745cd801eff3f96db?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e9b818c4bcbc06b196d66cea92d9fe41bd5ccd255dd3943745cd801eff3f96db?s=96&d=mm&r=g\",\"caption\":\"jmlweb\"},\"description\":\"Frontend Solutions Architect @ Freepik\",\"sameAs\":[\"https:\/\/jmlweb.es\"],\"url\":\"https:\/\/www.codemotion.com\/magazine\/author\/jmlweb\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u00bfC\u00f3mo funciona el renderizado en React? - Codemotion Magazine","description":"Aprende en este art\u00edculo de Jos\u00e9 Manuel Lucas c\u00f3mo funciona el ciclo de renderizado en React y qu\u00e9 herramientas est\u00e1n disponibles.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/","og_locale":"en_US","og_type":"article","og_title":"\u00bfC\u00f3mo funciona el renderizado en React?","og_description":"Aprende en este art\u00edculo de Jos\u00e9 Manuel Lucas c\u00f3mo funciona el ciclo de renderizado en React y qu\u00e9 herramientas est\u00e1n disponibles.","og_url":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/","og_site_name":"Codemotion Magazine","article_publisher":"https:\/\/www.facebook.com\/Codemotion.Italy\/","article_published_time":"2024-10-08T13:47:04+00:00","article_modified_time":"2024-10-08T13:47:05+00:00","og_image":[{"width":2560,"height":1707,"url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg","type":"image\/jpeg"}],"author":"jmlweb","twitter_card":"summary_large_image","twitter_creator":"@CodemotionIT","twitter_site":"@CodemotionIT","twitter_misc":{"Written by":"jmlweb","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#article","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/"},"author":{"name":"jmlweb","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/b38417c0c79c66c436a78f8b207c514a"},"headline":"\u00bfC\u00f3mo funciona el renderizado en React?","datePublished":"2024-10-08T13:47:04+00:00","dateModified":"2024-10-08T13:47:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/"},"wordCount":1677,"publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg","keywords":["Desarrollo web"],"articleSection":["Frontend"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/","url":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/","name":"\u00bfC\u00f3mo funciona el renderizado en React? - Codemotion Magazine","isPartOf":{"@id":"https:\/\/www.codemotion.com\/magazine\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage"},"thumbnailUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg","datePublished":"2024-10-08T13:47:04+00:00","dateModified":"2024-10-08T13:47:05+00:00","description":"Aprende en este art\u00edculo de Jos\u00e9 Manuel Lucas c\u00f3mo funciona el ciclo de renderizado en React y qu\u00e9 herramientas est\u00e1n disponibles.","breadcrumb":{"@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#primaryimage","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg","width":2560,"height":1707},{"@type":"BreadcrumbList","@id":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/como-funciona-el-renderizado-en-react\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codemotion.com\/magazine\/"},{"@type":"ListItem","position":2,"name":"Frontend","item":"https:\/\/www.codemotion.com\/magazine\/es\/frontend-es\/"},{"@type":"ListItem","position":3,"name":"\u00bfC\u00f3mo funciona el renderizado en React?"}]},{"@type":"WebSite","@id":"https:\/\/www.codemotion.com\/magazine\/#website","url":"https:\/\/www.codemotion.com\/magazine\/","name":"Codemotion Magazine","description":"We code the future. Together","publisher":{"@id":"https:\/\/www.codemotion.com\/magazine\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codemotion.com\/magazine\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.codemotion.com\/magazine\/#organization","name":"Codemotion","url":"https:\/\/www.codemotion.com\/magazine\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/","url":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","contentUrl":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2019\/11\/codemotionlogo.png","width":225,"height":225,"caption":"Codemotion"},"image":{"@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Codemotion.Italy\/","https:\/\/x.com\/CodemotionIT"]},{"@type":"Person","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/b38417c0c79c66c436a78f8b207c514a","name":"jmlweb","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codemotion.com\/magazine\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e9b818c4bcbc06b196d66cea92d9fe41bd5ccd255dd3943745cd801eff3f96db?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e9b818c4bcbc06b196d66cea92d9fe41bd5ccd255dd3943745cd801eff3f96db?s=96&d=mm&r=g","caption":"jmlweb"},"description":"Frontend Solutions Architect @ Freepik","sameAs":["https:\/\/jmlweb.es"],"url":"https:\/\/www.codemotion.com\/magazine\/author\/jmlweb\/"}]}},"featured_image_src":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-600x400.jpg","featured_image_src_square":"https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-600x600.jpg","author_info":{"display_name":"jmlweb","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/jmlweb\/"},"uagb_featured_image_src":{"full":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-scaled.jpg",2560,1707,false],"thumbnail":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-150x150.jpg",150,150,true],"medium":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-300x200.jpg",300,200,true],"medium_large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-768x512.jpg",768,512,true],"large":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-1024x683.jpg",1024,683,true],"1536x1536":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-1536x1024.jpg",1536,1024,true],"2048x2048":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-2048x1365.jpg",2048,1365,true],"small-home-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-100x100.jpg",100,100,true],"sidebar-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-180x128.jpg",180,128,true],"genesis-singular-images":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-896x504.jpg",896,504,true],"archive-featured":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-400x225.jpg",400,225,true],"gb-block-post-grid-landscape":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-600x400.jpg",600,400,true],"gb-block-post-grid-square":["https:\/\/www.codemotion.com\/magazine\/wp-content\/uploads\/2024\/10\/10200835-2-600x600.jpg",600,600,true]},"uagb_author_info":{"display_name":"jmlweb","author_link":"https:\/\/www.codemotion.com\/magazine\/author\/jmlweb\/"},"uagb_comment_info":0,"uagb_excerpt":"React es una de las librer\u00edas de c\u00f3digo abierto m\u00e1s conocidas para la construcci\u00f3n de UI y est\u00e1 basada en principios de programaci\u00f3n funcional y reactiva: \u00bfQu\u00e9 significa que un componente se renderiza? React funciona con el llamado Virtual DOM, que no es m\u00e1s que una representaci\u00f3n del DOM en memoria. Cuando detecta un cambio,&#8230;&hellip;","lang":"es","_links":{"self":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/29905","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/users\/254"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/comments?post=29905"}],"version-history":[{"count":2,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/29905\/revisions"}],"predecessor-version":[{"id":29963,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/posts\/29905\/revisions\/29963"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media\/29960"}],"wp:attachment":[{"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/media?parent=29905"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/categories?post=29905"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/tags?post=29905"},{"taxonomy":"collections","embeddable":true,"href":"https:\/\/www.codemotion.com\/magazine\/wp-json\/wp\/v2\/collections?post=29905"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}