mui-datatables: Reactive data causing table state to be lost
Currently using Meteor to generate reactive data, and if I change any table settings (filter, sort, etc), they are lost if any of the data is updated. Previously, I thought it was because there were functions in options and columns that were updating the props, but it seems even the data prop, if updated, causes the state to be lost (for me). A sample of my code:
import { LabClinics } from "/imports/api/labclinics/labclinics";
import ReactSelect from "/imports/ui/Components/ReactSelect.js";
import {
Button,
Grid,
IconButton,
Paper,
TextField,
Toolbar,
withStyles,
} from "@material-ui/core";
import CheckIcon from "@material-ui/icons/Check";
import { Meteor } from "meteor/meteor";
import { withTracker } from "meteor/react-meteor-data";
import MUIDataTable from "mui-datatables";
import React from "react";
import { toast } from "react-toastify";
class UsersComponent extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
data: [],
users: null,
options: this.returnOptions(),
columns: this.returnColumns(),
clinic: null,
};
this.onSubmit = this.onSubmit.bind(this);
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (this.props.isReady && this.props !== prevProps) {
this.createRows();
this.createClinicSelectOptions();
}
}
onChange(e) {
console.log(e.target.value);
this.setState({ [e.target.name]: e.target.value });
}
createClinicSelectOptions = () => {
const clinicOptions = this.props.clinics.map((clinic) => ({
label: clinic.AurusUser,
value: clinic,
}));
this.setState({ clinicOptions });
};
onChangeClinic = (value) => {
this.setState({ clinic: value });
};
returnOptions = () => ({
onRowsSelect: (currentRowsSelected, allRowsSelected) => {
if (currentRowsSelected.length <= 0) {
this.setState({ clinic: null, users: null });
} else {
const users = [];
currentRowsSelected.forEach((row) => {
users.push(this.state.data[row.dataIndex][0]);
});
this.setState({ users });
}
},
customToolbarSelect: (selectedRows, displayData, setSelectedRows) => {
return (
<Toolbar
style={{ flexGrow: 0.1 }}
className={"toolbar-spacing"}
>
{/*<Typography>Reassign User to Clinic:</Typography>*/}
{this.state.clinic && (
<React.Fragment>
<IconButton onClick={this.onSubmit}>
<CheckIcon fontSize={"small"} />
</IconButton>
</React.Fragment>
)}
<ReactSelect
options={this.state.clinicOptions}
placeholder={"Reassign User to Clinic"}
// label={"Reassign User to Clinic"}
helperText={"Reassign User to Clinic"}
onChange={this.onChangeClinic}
/>
</Toolbar>
);
},
elevation: 1,
});
createRows = () => {
const data = this.props.users.map((user) => [
user,
user.profile.username,
user.profile.clinicId,
]);
this.setState({ data });
};
returnColumns = () => [
{
name: "User",
options: {
display: "excluded",
},
},
{
name: "Username",
},
{
name: "Clinic ID",
},
];
render() {
const { classes } = this.props;
const { data, options, columns } = this.state;
return (
<MUIDataTable
title={"Users"}
data={data}
options={options}
columns={columns}
/>
);
}
}
const styles = (theme) => ({
iconButton: {},
iconContainer: {
marginRight: "24px",
},
inverseIcon: {
transform: "rotate(90deg)",
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
},
paper: {
...theme.mixins.gutters(),
paddingTop: theme.spacing(2),
paddingBottom: theme.spacing(2),
},
});
export default withTracker((props) => {
const handles = [
Meteor.subscribe("labClinics"),
Meteor.subscribe("userList"),
];
const isReady = handles.every((e) => e.ready());
let clinics, users;
if (isReady) {
clinics = LabClinics.find().fetch();
users = Meteor.users.find().fetch();
debugger;
}
return {
isReady,
clinics,
users,
};
})(withStyles(styles)(UsersComponent));
Expected Behavior
Table state should be retained (filters, search text, etc) should any prop update on the MUIDataTable.
Current Behavior
All state resets if any changes in props are made (denoted by “propsChange” in onTableChange).
Steps to Reproduce (for bugs)
- Created new Meteor project and populated with test data.
- Fed data into datatable.
- De-selected a column from “View Columns”.
- Opened database editor and changed a value in the database to see if reflected reactively in table.
- Witnessed the de-selected column then become visible again on data change.
Your Environment
| Tech | Version |
|---|---|
| Material-UI | 4.1.3 |
| MUI-datatables | 2.5.1 (but tested it on 2.4.0, 2.3.0, and 2.2.0 |
| React | 16.8.6 |
| browser | Chrome Version 75.0.3770.100 (Official Build) (64-bit) |
| OS | MacOS 10.14.5 |
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 23
I can validate this Bug, A propsUpdate event is triggering and resetting table state.
State in table is persistent as of version 2.15.0.
It’d be great if there was a way to serialize the whole state and pass it as modified object. A example on saving the whole state and passing it would be greatly appreciated.