React-data-grid: Lazy loading

Created on 28 Apr 2016  路  19Comments  路  Source: adazzle/react-data-grid

Is there any way to scroll to a specific point and then trigger another ajax request to server to load more in the grid?

Question Will Accept PR wontfix

Most helpful comment

I was able to work around this issue as well by wrapping the ReactDataGrid component, and setting state to contain the newly loaded rows. Something like:

class Datagrid extends Component {
  constructor(props) {
    super(props);
    this.asyncRowGetter = this.asyncRowGetter.bind(this);
    this.rowStatus = [];
    this.state = {
      rows: [],
    };
  }
  render() {
    return (
      <ReactDataGrid columns={this.props.columns}
        rowGetter={this.asyncRowGetter}
        rowsCount={this.props.rowCount}/>);
  }
  asyncRowGetter(rowIndex) {
    let result = this.props.defaultRow;
    if (!this.state.rows[rowIndex]) {
      if (!this.rowStatus[rowIndex]) {
        this.props.getRow(rowIndex).then((response) => {
          const rows = this.state.rows.slice(0);
          rows[rowIndex] = response;
          this.setState({
            rows: rows
          });
        });
        this.rowStatus[rowIndex] = true;
      }
    } else {
      result = this.state.rows[rowIndex];
    }
    return result;
  }
}

So then you can consume it like this:

<Datagrid rowCount={500} getRow={(rowIndex) => {/*getRow async as promise*/}} columns={columns} defaultRow={deafaultRowObject}/>

All 19 comments

This is not currently possible, but is on our roadmap

Maybe this could be solved by just allowing rowGetter() to return a promise?

This is something we are interested in as well. Has this work been scheduled for a future release or has work yet to begin?

I was able to work around this issue as well by wrapping the ReactDataGrid component, and setting state to contain the newly loaded rows. Something like:

class Datagrid extends Component {
  constructor(props) {
    super(props);
    this.asyncRowGetter = this.asyncRowGetter.bind(this);
    this.rowStatus = [];
    this.state = {
      rows: [],
    };
  }
  render() {
    return (
      <ReactDataGrid columns={this.props.columns}
        rowGetter={this.asyncRowGetter}
        rowsCount={this.props.rowCount}/>);
  }
  asyncRowGetter(rowIndex) {
    let result = this.props.defaultRow;
    if (!this.state.rows[rowIndex]) {
      if (!this.rowStatus[rowIndex]) {
        this.props.getRow(rowIndex).then((response) => {
          const rows = this.state.rows.slice(0);
          rows[rowIndex] = response;
          this.setState({
            rows: rows
          });
        });
        this.rowStatus[rowIndex] = true;
      }
    } else {
      result = this.state.rows[rowIndex];
    }
    return result;
  }
}

So then you can consume it like this:

<Datagrid rowCount={500} getRow={(rowIndex) => {/*getRow async as promise*/}} columns={columns} defaultRow={deafaultRowObject}/>

Thanks for sharing but how to achieve the same on scroll down (It should call only if scroll downs nearly to bottom)

This is achieved automatically. The rowGetter is only called when the react-data-grid attempts to render (or will soon render) the row. So as you scroll, your asyncRowGetter will get called with successively a higher rowIndex.

Oh ok. Thanks for your answer.
But somehow its not calling the asyncRowGetter in vertical scroll dowon, its calling when I try to scroll horizontal one.

FYI I am using typescript to achieving this.

Request for comments: https://github.com/adazzle/react-data-grid/commit/601571ca67ce2eb1ce8bc5f3867a09b5f1ecca21

Support asynchronous rowGetter

The `rowGetter` gets called with a second, optional parameter end. If its
return value owns the property `then`, it get treated as a
Promise. Otherwise it might return an array with all rows with (`begin <=
idx && idx < end`) or a single row at `begin` (the old behaviour).

While the promise is not fulfilled, a blank content of the table gets
shown or an optional panel, provided by the property `loadingView` of
ReactDataGrid. This view gets the properties `loading` and `width` and
might return a `<div hidden=!loading>` or `undefined`.

@jo-so It's awesome ! Have your changes already been merged?
If I understand it right, basically this would allow to load on demand a specific page. So it allows endless pagination/load while scrolling pattern.

Do you think we could have an example on : http://adazzle.github.io/react-data-grid/examples.html#/all-features ?

@molinch No, it hasn't been merged, yet. I didn't send a pull request, because I would like to get some feedback and if it works for others.

BTW: I've rebased my commit on the current master. https://github.com/jo-so/react-data-grid/tree/lazy-loading

I'll create an example for this feature, too. :-)

I've added an example to my branch.

@molinch I've extended the example to cache the "fetched" data. This seams to me more meaningful as an example. What do you think?

Thanks a lot @jo-so it's working fine and the example is really easy to understand!

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Please reopen this if you feel it has been incorrectly closed and we will do our best to look into it. Thank you for your contributions.

@jo-so did this feature meet some negative feedback or something? Wondering why it's not included.

@BlaineBradbury No, never heard something.

Would love for this to be merged.

+1 for @jo-so PR, has it been merged at some point? if not what's the view of the maintainers on this PR?

v7 canary supports lazy loading and we recommend upgrading. rowGetter will be removed in v7 and we have added a new rows prop and now it is possible to use the scroll event to lazy load rows

https://github.com/adazzle/react-data-grid/blob/canary/CHANGELOG.md
https://adazzle.github.io/react-data-grid/canary/?path=/story/demos--all-features
https://github.com/adazzle/react-data-grid/blob/canary/stories/demos/AllFeatures.tsx#L211

Was this page helpful?
0 / 5 - 0 ratings