I have created a Material-Table with the following options:
options={{
pageSize: 25,
paging: true,
pageSizeOptions: [25, 50, 100, 200],
sorting: true,
selection: true,
search: false,
headerStyle: {
position: "sticky",
top: 0,
fontWeight: 800,
textAlign: "center"
},
maxBodyHeight: "850px",
draggable: true
}}
I reload the data if a text filter is entered. [Note - I cannot use the inbuilt text filter. I need to reload the table from the database].
loadTableWithFilter(filter) {
this.setState({ filterText: filter});
//Set flag to indicate this is a table reload from first page
this.setState({ reloadTableCustom: true });
this.tableRef.current.onQueryChange();
}
The flag "reloadTableCustom" is used to indicate that the whole table should be loaded from the beginning after a text search in an external widget:
tableRef={this.tableRef}
onSelectionChange={data => this.selectionChanged(data)}
data={query =>
new Promise((resolve, reject) => {
let url = "";
url = 'My Webservice URL with page iptions'
fetch(url).then(response => respose.json())
.then(result => {
var data = result.data;
var pagenum = query.page;
//If this table load is due to external filter
//set to first page (0).
if (this.state.reloadTableCustom === true) {
pagenum = 0;
}
//I set this flag to note that the page is reloaded due to a custom event.
//Since it is reloaded, I reset this variable
this.setState({ reloadTableCustom: false });
resolve({
data: groups,
page: pagenum,
totalCount: result.totalElems
});
});
})
}
When I use this approach the component reloads a second time after every event & page size is not retained when I change the page size. The data size retrieved is correct, but still the page size stays the same.
I removed this line before the render method and got it working:
this.setState({ reloadTableCustom: false });
I used this state variable to differentiate the table being reloaded due to a text filter (a custom event to trigger a remote[not local] text search) and due to table events (sorting, pagination, etc). The reason was to load the first page of the table when a remote filter was applied, versus the active page when a table event was applied. If I do not maintain the page number like this, the table tries to load in its current active page. If the result is smaller than before, the page just goes blank.
My question - Why does this state change cause the page size setting to be erased? How can I differentiate the table reload events due to a pagination vs custom event?
This is how I solved the issue. If the state is changed in the material-table's resolve() method, it will trigger the parent component to reload, which will again reload the material-table with default page size. This can be controlled using the shouldComponentUpdate method.
I override the shouldComponentUpdate method. I have a flag "renderFlag". In this method I check the renderFlag to decide if the conponent should be reloaded.
shouldComponentUpdate(nextProps, nextState) {
if (!renderFlag) {
renderFlag = true;
return false;
} else {
return true;
}
}
When updating the state set the flag to false.
//Set the flag to false.
renderFlag = false;
//Update the state
this.setState({ reloadTableCustom: false });
This stops the component from reloading when the state is changed.