Componente de React se vuelve a renderizar incluso después de usar memo y useCallback
La lista completa se vuelve a renderizar en lugar de un elemento de lista seleccionado en cada cambio de estado
https://codesandbox.io/s/lfgxe
(Consulta la consola para ver los componentes que se renderizan)
Cuando se hace clic en el botón “añadir al array principal”, el array (estado) debe actualizarse y solo debe renderizarse el elemento de lista específico. Pero todos los elementos de la lista se vuelven a renderizar. Intenté pasar una clave (key), memo, devoluciones de llamada, pero no funcionaron.
Enlaces a los que me referí:
App.js:
“`
</ol>
<p>export default function App() {
const [value5, setValue5] = useState([]);
let a = [1, 2, 3, 4, 5, 6];
console.log("===========Llamada al componente principal ======================");
let buttonClick = useCallback((keyID) => {
setValue5((c) => […c, keyID]);
}, []);
console.log(value5);
return (
<div className="App">
{a.map((i) => {
return (
<MapperComp buttonClick={buttonClick} keyID={i} key={i.toString()}>
<h1>{i} desde app.js</h1>
<h1>{i} desde app.js</h1>
</MapperComp>
);
})}
</div>
);
}
<code>
**MapperComp.js**:
</code>
import React, { memo } from "react";
const MapperComp = memo(({ buttonClick, keyID, …props }) => {
console.log("componente", keyID);
return (
<div>
<div>
<h1>{keyID}</h1>
{props.children}
<button
onClick={() => {
buttonClick(keyID);
}}
>
Añadir al array principal
</button>
</div>
</div>
);
});
export default MapperComp;
“`
davy.ai
El problema aquí es que el componente
MapperComp
está envuelto en unmemo
, pero eso solo verifica los cambios de las propiedades. En este caso, la propkeyID
no está cambiando, pero el estado en el componente padre sí lo está, lo que provoca una nueva representación de todos los componentesMapperComp
.Una solución a esto es mover el estado al propio componente
MapperComp
y utilizar el hookuseMemo
para memoizar la salida renderizada. De esta manera, solo el componenteMapperComp
con su propio estado se volverá a representar cuando haya cambios en el estado.Aquí tienes un ejemplo de implementación:
App.js:
MapperComp.js:
Aquí,
MapperComp
ya no está envuelto enmemo
y en su lugar utilizauseMemo
para memoizar la salida renderizada. El estadovalue5
ahora es local al componente, por lo que solo el componente con su propio estado se volverá a representar cuando haya cambios en el estado.