Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

129
Vistas
react-window stop unnecessary rendering of child FixedSizeList rows when scrolling parent FixedSIzeList

In my react project I am using react-window package to render nested lists. Each parent FixedSizeList row renders a component which uses another FixedSizeList. Parent List doesn't have more than 14 rows at the moment. But the child List may contain upto 2000 rows. Now my problem is, when I try to scroll through the parent List, all the child list items in the viewport seem to re rendering. This is a little bit problematic for me because in my child list item I am using d3js to draw bar chart with transition effect. So these unnecessary re rendering is giving a overall weird UI. Can anyone help me how can I stop these unnecessary renders.

Here is codesandbox link to a very simple example of my problem. Please open the console log. After initial load the topmost log should be like this: initial console log.

Then if you clear the console and scroll the parent list, you will see log like this: console log after parent scrolling. Here you can see that the child list items of child list 0 is re rendering which is not needed for me.

Can anyone give me a solution that can stop these re rendering?

*P.S. I am not using memo since every row is updating the dom on its own.

Edit

I think this problem would solve if the parent list would stop propagating scroll event to child. I tried to add event.stopPropagation() and event.stopImmediatePropagation() in the parent list row but the output was the same as earlier.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

We can use memo to get rid of components being re-rendered unnecessarily for same set of props. And use useCallback to prevent re-creation of a function and thus secure child components being re-rendered. Applying those, we can get this solution:

import "./styles.css";
import { FixedSizeList as List } from "react-window";
import { memo, useCallback } from "react";

const Row = memo(({ index: parentIndex, style: parentStyle }) => {
  console.log("rendering child list", parentIndex);

  const InnerRow = useCallback(({ index, style }) => {
    console.log("rendering child list item", index, "of parent ", parentIndex);
    return <div style={style}>Child Row {index}</div>;
  }, []);

  return (
    <div style={parentStyle}>
      <List height={200} itemCount={1000} itemSize={35} width={270}>
        {InnerRow}
      </List>
    </div>
  );
});

const Example = () => {
  console.log("rendering parent list");
  return (
    <List height={400} itemCount={16} itemSize={300} width={300}>
      {Row}
    </List>
  );
};

export default function App() {
  return (
    <div className="App">
      <Example />
    </div>
  );
}
about 4 years ago · Juan Pablo Isaza Denunciar

0

although the above code works fine, it can be optimized more if we use areEqual method from react-window as react memo dependency. And for more if we want to use other react hooks inside InnerRow component, we must add a middleware component of InnerRow. The full example is given below:

  import { FixedSizeList as List, areEqual } from "react-window";
  import { memo, useCallback } from "react";

  const Row = memo(({ index: parentIndex, style: parentStyle }) => {
    console.log("mounting child list", parentIndex);
    const data = new Array(15).fill(new Array(500).fill(1));
    const InnerRowCallback = useCallback(
      ({ index, style }) => {
        return <InnerRow index={index} style={style} />;
      },
      [data]
    );
    const InnerRow = ({ index, style }) => {
      console.log("mounting child list item", index, "of parent ", parentIndex);
      return <div style={style}>Child Row {index}</div>;
    };
    return (
      <div style={parentStyle}>
        <List height={200} itemCount={1000} itemSize={35} width={270}>
          {InnerRowCallback}
        </List>
      </div>
    );
  }, areEqual);
  const Example = () => {
    console.log("mounting parent list");
    return (
      <List height={400} itemCount={16} itemSize={300} width={300}>
        {Row}
      </List>
    );
  };

  export default function App() {
    return (
      <div className="App">
        <Example />
      </div>
    );
  }

Here I am passing data array as useCallBack dependency because I want to re render the InnerRow component if data gets changed.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda