4

I am trying to implement react-window but Ia m not sure how to pass in a component that takes in it's own properties

If I have something like this

{
  items.map(
    (item, index) => {
      <MyComponent
        key={key}
        item={item}
      />;
    }
  );
}

how do I make a variable list?

The example does not show how to do this

import { VariableSizeList as List } from 'react-window';

// These row heights are arbitrary.
// Yours should be based on the content of the row.
const rowHeights = new Array(1000)
  .fill(true)
  .map(() => 25 + Math.round(Math.random() * 50));

const getItemSize = index => rowHeights[index];

const Row = ({ index, style }) => (
  <div style={style}>Row {index}</div>
);

const Example = () => (
  <List
    height={150}
    itemCount={1000}
    itemSize={getItemSize}
    width={300}
  >
    {Row}
  </List>
);
chobo2
  • 83,322
  • 195
  • 530
  • 832

1 Answers1

7

The example is indeed confusing. This example shows how you can use react-window with an array of data instead of the generative example that the homepage shows:

class ComponentThatRendersAListOfItems extends PureComponent {
  render() {
    // Pass items array to the item renderer component as itemData:
    return (
      <FixedSizeList
        itemData={this.props.itemsArray}
        {...otherListProps}
      >
        {ItemRenderer}
      </FixedSizeList>
    );
  }
}

// The item renderer is declared outside of the list-rendering component.
// So it has no way to directly access the items array.
class ItemRenderer extends PureComponent {
  render() {
    // Access the items array using the "data" prop:
    const item = this.props.data[this.props.index];

    return (
      <div style={this.props.style}>
        {item.name}
      </div>
    );
  }
}

While itemsArray is not provided in the code sample, ostensibly you would include the props you need to pass to ItemRenderer in it, such as name as shown here. This would leave your usage looking something like this:

<ComponentThatRendersAListOfItems
  itemsArray={[{ name: "Test 1" }, { name: "Test 2" }]}
/>
coreyward
  • 77,547
  • 20
  • 137
  • 166
  • ok, I will try this. This seems to make more sense. On a different subject, I want to have space between each item in this list. I been trying to do margin: 20px, but it does not seem to put any gaps between the records. – chobo2 May 21 '19 at 18:49
  • Thanks for this! it's not immediately clear from the docs how to a) pass in an array of your own data and b) how to reference this data in the rendered component (which is referenced via the 'data' prop!). – Nats Dec 12 '20 at 15:20
  • This is a good answer, but it can be improved if you expand on the properties that can be passed to the parent and how to access them from the child. Something to the effect of itemData={{array, checkedItems, handleClickItem}} – Bro3Simon Aug 10 '22 at 12:44