8

I have a table with >30 rows and >50 columns. Each row and each cell is a specific React component, since you can manipulate them and they change behaviour and look based on changing data.

So my component hierachy looks like this:

Grid -> Row -> Cell

I am using MobX to handle the application state and it seems to slow down a bit, when it comes to state changes that affect some cell components. Since not every cell and row is visible to the user (the table is scrollable) I thought that it might be an performance improvement to only let React components that are actually visible.

I wondered if there might be an existing component or how I would approach creating such a component in a performant way.

Also I recognized that cells und rows rerender every time the state changed. Maybe it has something to do with the fact, that every cell and row component injects the appStore. How do I tell MobX that it should only rerender those changed components? Is that even possible?

So basically I am looking for either way.

Johannes Klauß
  • 9,087
  • 13
  • 59
  • 110

4 Answers4

8

I'd go with react-visibility-sensor.

Something like:

const VisibilitySensor = require('react-visibility-sensor');

class TableRow extends React.Component {
    onChange(isVisible) {
        this.setState({ isVisible });
    };

    render () {
        const { isVisible } = this.state;

        return (
            <VisibilitySensor onChange={onChange}>
                {isVisible && {/* Table row content */}}
            </VisibilitySensor>
        );
     }
} 
Daniel
  • 5,560
  • 5
  • 28
  • 53
8

A little late to this party. But React Virtualized has been pretty good to me.

jgillich
  • 56,006
  • 5
  • 49
  • 79
mccambridge
  • 910
  • 7
  • 16
2

I am not familiar with Mobx or any solutions related to that, but only showing visible components has taken on the name "Infinite" components in the community. So searching "Infinite Scroll" or "Infinite List" may give you some ideas.

The best library I have found and enjoy using is react-infinite. Basically the library is a HOC that you pass children components to.

If you are looking for a purely JavaScript implementation with no 3rd party libraries, Ben Alpert from the facebook team posted this fiddle/code on SO.

Community
  • 1
  • 1
erik-sn
  • 2,377
  • 16
  • 32
1

You can use React's shouldComponentUpdate (PureComponent implements it out of the box) on your row component to prevent rerendering. If you have a <Row key={person.id} person={person} edit={this.edit}/>, SCU compares person and edit props and if they are same, prevents rerendering that row. So when you append to rows, only the changed rows rerender.

This optimization will be thwarted if key prop is array index or edit function is an inline function - edit={this.edit} presents same reference each time, edit={() => this.edit(person.id} presents a different reference each time.

https://60devs.com/pure-component-in-react.html

https://mobx.js.org/best/react-performance.html

Jesvin Jose
  • 20,780
  • 25
  • 95
  • 183