How to wrap material-ui ListItem in react-virtualized autosizer

5.2k views Asked by At

I was using material-ui's List and ListItem components. Specifically, I was using the nested items functionality. See http://www.material-ui.com/#/components/list around half way down the page you'll see Nested List. The point is: material-ui takes care of the 'nesting' issues such as indentation and also the expand/contract arrow.

Once I added many items I realized that the list is extremely slow. So I chanced upon AutoSizer from react-virtualized. The problem is: In react-virtualized my code would need to supply a rowRenderer function for each row. I don't want to lose the built in material-ui functionality that figures out the indentation for the nested items. Yet using AutoSizer it seems like my code would need to do custom work to figure out the indentation. Also my code would nned to supply the expand/contract arrow. Currently it comes for free with material-ui's List/ListItem.

Any tips or suggestions?

Thank you

1

There are 1 answers

2
AudioBubble On

You may want to consider using a "virtual" list library like this one: https://github.com/bvaughn/react-virtualized

Usually these libraries give you a way to create a custom list container and a custom list item.

Here's example code of how to do this:

import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";

// NOTE: Your import path for react-virtualized may be different if you are
//       using TypeScript or ES6/Babel or UMD modules.
import { List } from "react-virtualized";

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      ids: ["abc", "def", "ghi"]
    };
  }

  // the rowRenderer function is given an object with a lot more stuff
  // in it: https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md
  rowRenderer = ({ key, index, style }) => {
    const value = this.state.ids[index];
    return (
      <ListItem key={key} style={style}>
        <ListItemText>{value}</ListItemText>
      </ListItem>
    );
  }

  render() {
    return (
      <List
        height={150} width={250} rowHeight={30}
        rowCount={this.state.ids.length}
        rowRenderer={this.rowRenderer} />
    );
  }
}