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.

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í:

  1. App.js:
    “`

  2. </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;

    “`

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí es que el componente MapperComp está envuelto en un memo, pero eso solo verifica los cambios de las propiedades. En este caso, la prop keyID no está cambiando, pero el estado en el componente padre sí lo está, lo que provoca una nueva representación de todos los componentes MapperComp.

    Una solución a esto es mover el estado al propio componente MapperComp y utilizar el hook useMemo para memoizar la salida renderizada. De esta manera, solo el componente MapperComp con su propio estado se volverá a representar cuando haya cambios en el estado.

    Aquí tienes un ejemplo de implementación:

    App.js:

    import React from "react";
    import MapperComp from "./MapperComp";
    
    export default function App() {
      let a = [1, 2, 3, 4, 5, 6];
      console.log("===========Llamada al componente padre ======================");
    
      return (
        <div classname="App">
          {a.map((i) => {
            return (
              <mappercomp keyid="{i}" key="{i.toString()}">
                <h1>{i} desde app.js</h1>
                <h1>{i} desde app.js</h1>
              </mappercomp>
            );
          })}
        </div>
      );
    }
    

    MapperComp.js:

    import React, { useState, useMemo } from "react";
    
    const MapperComp = ({ keyID, ...props }) => {
      const [value5, setValue5] = useState([]);
    
      console.log("componente", keyID);
    
      const handleClick = () => {
        setValue5((c) => [...c, keyID]);
      };
    
      const renderedOutput = useMemo(() => {
        return (
          <div>
            <h1>{keyID}</h1>
            {props.children}
            <button onclick="{handleClick}">Añadir al array principal</button>
            <div>{value5.join(", ")}</div>
          </div>
        );
      }, [keyID, props.children, value5]);
    
      return renderedOutput;
    };
    
    export default MapperComp;
    

    Aquí, MapperComp ya no está envuelto en memo y en su lugar utiliza useMemo para memoizar la salida renderizada. El estado value5 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.

Comments are closed.