Sin embargo, el contexto nos permite hacer un poco de trampa y evitar ese árbol de componentes. Si simplemente extraemos estos datos que queremos pasar al contexto y los usamos directamente en el componente rosa, entonces solo el componente con los datos en sí y el componente que realmente los usa se re-renderizarán. El resto de la aplicación simplemente se quedará ahí tranquilamente y no hará absolutamente nada.
Bien, los gatitos son divertidos, pero echemos un vistazo más de cerca a la vida normal y a los componentes normales. Supongamos que quiero implementar una página que se vea así. Diseño de página de dos columnas, navegación a la izquierda, área de contenido principal a la derecha. En la navegación quiero tener un botón que expanda y colapse la navegación. Y quiero renderizar un número diferente de bloques en la parte inferior del área de contenido dependiendo de si la navegación está expandida o colapsada. Si empiezo a implementarlo con props normales, se vería algo así. Tendríamos una página que mantiene el estado de navegación, pasa ese estado al botón que lo expande a través del componente de navegación y escucha el callback en él. Y luego tendríamos que pasar estos datos al componente de página a través de todas las capas hacia abajo, hacia abajo, hacia abajo hasta el nivel donde están esos bloques que necesito renderizar. Y nuevamente, desde la perspectiva de las re-renderizaciones no es genial. Cada expansión o colapso de la navegación resultará en re-renderizaciones de absolutamente todo.
Lo que puedo hacer en su lugar aquí es extraer esta lógica de expansión y colapso en el contexto, solo la lógica, nada más. Esto se vería algo así, el mismo estado que controla la navegación, tendríamos un valor al que pasaríamos el estado en sí y la función de alternar, y luego pasaríamos este valor al proveedor de contexto. De repente nuestra página, en lugar de toneladas de código y props por todas partes, simplemente se convierte en algo tan limpio como esto. Contexto en la parte superior, navegación, y contenido pasados a él como hijos. Y luego en algún lugar de la navegación, tendríamos el botón que simplemente usa la función de alternar directamente del contexto. Y en algún lugar del área de contenido, tendríamos el bloque con elementos que usan el estado de navegación directamente del contexto.
Pero aunque este ejemplo se ve genial en teoría, en la vida real es, por supuesto, un poco más complicado, como siempre. En la vida real, todavía tenemos un problema con el contexto que tiene mala reputación por las re-renderizaciones. Principalmente esta reputación proviene de dos hechos. El primero es que las re-renderizaciones relacionadas con el contexto se desencadenarán en cada hijo que use este hook de contexto, independientemente de si usa los datos reales o no. Así que en nuestro caso, el componente a la izquierda que solo usa la función de alternar, en teoría, no debería preocuparse por el estado en absoluto, pero en la práctica, ambos componentes se re-renderizarán cuando el contexto cambie. Y el segundo problema aquí es que esas re-renderizaciones son imparables. No hay una forma sensata de prevenirlas. Usar memo o hooks de callback no ayudará. Sin embargo, hay otro truco que puede ayudar aquí si este comportamiento realmente causa problemas de rendimiento. Podemos simplemente dividir esos proveedores de contexto en dos. En lugar de un solo valor que contenga tanto la función de alternar como el estado, podemos tener dos valores separados.
Comments