Obtuve un componente <Accordion/>
que puede contener múltiples componentes <AccordionItem/>
. Preparé una demostración de codesandbox aquí .
El problema actualmente es que en el procesamiento inicial, todos los componentes <AccordionItem/>
se procesan (verifique los registros de la consola en el ejemplo de codesandbox). Entonces, dependiendo del tamaño de la matriz que use el componente <Accordion/>
para representar todos los elementos, esto significa muchas representaciones iniciales. Además, cada vez que se abre un <AccordionItem/>
, todos los elementos dentro del <Accordion/>
se vuelven a renderizar . Por el bien del rendimiento, esto podría no ser un problema con solo algunos elementos. Sin embargo, en mi aplicación, pueden ser 10 componentes <AccordionItem/>
que tienen un acordeón anidado que se vuelve a renderizar constantemente cada vez que un usuario abre uno. Entonces, esto puede significar que cada vez que un usuario abre un elemento, ocurren aproximadamente 50 renderizaciones.
Ya he probado un montón de cosas para eliminar esto. Por ejemplo, el acordeón se basa en un booleano active
. Entonces, solo representar el cuerpo del acordeón cuando este booleano active
es verdadero elimina el problema, así:
<div className="answer">{active && <AccordionBody />}</div>
Sin embargo , la animación desplegable deja de funcionar y el cuerpo no se abre por completo. ¿Qué puedo hacer para representar solo el clic en <AccordionItem/>
y su cuerpo mientras mantengo la agradable animación desplegable?
En términos generales, debe dejar que React vuelva a renderizar cuando necesite volver a renderizar.
Está iniciando sesión incorrectamente en la consola en el cuerpo de la función del componente AccordionBody
como un efecto secundario involuntario; sin embargo, incluso después de mover la consola inicia sesión en un useEffect
( recuerde que useEffect
hook se llama una vez por procesamiento ), el AccordionBody
todavía se vuelve a renderizar como parte de el componente Accordion
vuelve a representar la matriz de preguntas faqs
cuando se actualiza el estado.
Los componentes de React se vuelven a renderizar cuando se actualizan el estado o los accesorios, o cuando se vuelve a renderizar su componente principal. Cuando un componente vuelve a renderizar, necesariamente vuelve a renderizar todo el subárbol de componentes (es decir, sus hijos).
Estos renderizados adicionales generalmente son económicos y no necesariamente son un problema por sí solos. Realmente depende de lo que haga cada componente que se vuelve a renderizar cuando se vuelve a renderizar. ¡No optimice prematuramente!
Las herramientas que puede usar para mejorar el rendimiento, si hay un problema, son memorizar accesorios, es decir, usar useMemo
o useCallback
para proporcionar referencias de accesorios estables.
También puede memorizar componentes con el memo Componente de orden superior. Dado que el componente genera el mismo resultado con los mismos accesorios, puede memorizar el resultado generado. En su código de ejemplo, esto elimina las representaciones duplicadas.
AcordeónCuerpo
import React, { memo, useEffect } from "react"; function AccordionBody() { useEffect(() => { console.log("AccordionBody rendered"); // <-- log once per render }); return ( <div> <div>All of the AccordionBody's are rendered</div> <div>So everytime an accordion item is openend</div> <div>The AccordionBody component gets rendered 3 times</div> <div>1 for every faq in the faqs array</div> <div>How will this impact performance in a large array?</div> <div> How do I stop these recursive re-renders, while maintaining the animation? </div> </div> ); } export default memo(AccordionBody); // <-- memoize render result
Nota: No optimice prematuramente, pero solo intente optimizar cuando encuentre un problema de rendimiento o representación. Por lo general, esto se hará caso por caso.