Whenever the state of a parent is set the table loses its filter controls.
1 - Add a value to a column filter
2 - Trigger setState on the parent component
3 - Observe that the table is no longer filtered (even if the HTML input box has text)
Expected behavior: Filter selections persist in the table state and are applied whenever the table is rendered.
I suspect this has to do with the UNSAFE_componentWillReceiveProps method invoking setState without any regard from the previous state / props or input contents and reimposing defaults.
Hi @martindeanlund ,
I will look at it asap.
MaterialTable store sorting, filtering and other values of every column on columnDefinition. If you send columns as renewed every time it will be resetted. So try giving columns array to columns from state of your component instead of giving [array] directly.
MaterialTable store sorting, filtering and other values of every column on columnDefinition. If you send columns as renewed every time it will be resetted. So try giving columns array to columns from state of your component instead of giving [array] directly.
Can you explain this more. I am confused by what "column" means above.
I have an array that I pass into the data prop of MaterialTable and when ever I change the state of that array it resets all filters. How can I avoid the resetting of the filters?
Do not send column directly to table. Set your columns array in your components state. Then give this state variable to table.
state = {
columns: [...]
}
render() {
<MaterialTable columns={this.state.columns}(/>
}
Hi @mbrn,
Thanks for your solution.
However when I am trying it I still don't manage to obtain the expected result. The filter is indeed not reset, but the data inside the table is not updated anymore. To be more specific, some cells should have their style updated but nothing is happening. Like this one where the cell's color could be updated by the parent:
{
title: 'Staff',
field: 'staffUserName',
render: rowData => {
const color = rowData.staffColor
return (
<div style={{ backgroundColor: color }}>
{rowData.staffUserName}
</div>
)
},
}
Any guess or workaround?
Cheers
@dz0l038 You need to set the columns to state at the time of setting the state. try both before and after updating the rows data.
@johnjayasingh thanks for your comment and sorry for my late reply. Unfortunately, it didn鈥檛 solve my issue (or maybe I didn鈥檛 understand your solution), the filter was updated but not the content. I get it working anyway so here is my solution, maybe it could help someone in the future.
First, to be clear about what I was trying to achieve:
The default behavior of material table is to have the filter cleared at data update, and if I set columns in a state, the content is not updated and filtered based on the new data.
My solution is to use ref as follow:
import React, { useRef } from "react"
import MaterialTable, { MTableBody } from 'material-table'
const ListAssignation = (props) => {
let filterRef = useRef("")
const assignToUser = async (rowsSelected) => {
// Do some action here that update your data
}
const unassignTask = async (rowsSelected) => {
// Do some action here that update your data
}
return (
<MaterialTable
components={{
Body: props => <MTableBody {...props} onFilterChanged={(columnId, value) => {
props.onFilterChanged(columnId, value);
filterRef.current = value
}} />
}}
columns={[
{
title: 'Staff',
field: 'staffColumnName',
defaultFilter: filterRef.current,
render: rowData => {
const color = rowData.staffColor
return (
<div style={{ backgroundColor: color }}>
{rowData.staffColumnName}
</div>
)
},
}
]}
actions={[
{
icon: 'add',
tooltip: 'Assign',
onClick: (event, rowSelected) => {
assignToUser(rowSelected);
},
},
{
icon: 'remove',
tooltip: 'Unassign',
onClick: (event, rowSelected) => {
unassignTask(rowSelected);
},
},
]}
options={{
actionsColumnIndex: -1,
selection: true,
filtering: true,
}}
data={props.listTasks}
title=""
/>
)
}
export default ListAssignation
Most helpful comment
MaterialTable store sorting, filtering and other values of every column on columnDefinition. If you send columns as renewed every time it will be resetted. So try giving columns array to columns from state of your component instead of giving [array] directly.