Closed sk364 closed 4 years ago
Hard to tell without any code or a sandbox, but if I had to guess you need to make sure your data is being updated via React State and that DataTable is using that state.
// TitleCell.jsx
import React from "react";
import { connect } from "react-redux";
const TitleCell = props => {
const { row, onFetchSubObjects, onUnexpandRow } = props;
return(<div onClick={() => {
if (!row.isExpanded) onFetchSubObjects(row);
else onUnexpandRow(row.id);
}}>
{ /* some html */ }
</div>);
};
export default connect(undefined, dispatch => {
return {
onFetchSubObjects: row => {
// dispatches redux event to fetch sub objects which is picked by a saga
// which after successful fetch will dispatch an event with the fetched
// objects, which is then picked by the reducer to update the table data
},
onUnexpandRow: rowId => {
// dispatches redux event to set `isExpanded` to false
}
}
})(TitleCell);
// Table.jsx
import React from "react";
import DataTable from "react-data-table-component";
import { connect } from "react-redux";
import TitleCell from "./TitleCell";
import SubTable from "./SubTable";
const columns = [
{
id: "title",
name: "Title",
sortable: true,
right: true,
cell: row => <TitleCell row={row} />
},
{
// ... more columns
}
];
const Table = props => {
const { data, onFetchSubObjects } = props;
const handleRowExpansion = (isExpanded, row) => {
if (isExpanded) onFetchObjects(/* params */);
};
return(
<DataTable
data={data}
columns={columns}
expandableRows
expandableRowsComponent={<SubTable columns={columns} />}
onRowExpandToggled={handleRowExpansion}
expandOnRowClicked={false}
expandableRowExpanded={row => row.isExpanded}
);
};
export default connect(
state => {
return {
data: getTableData(state),
};
},
dispatch => {
onFetchObjects: () => {}
}
)(Table);
// tableReducer.jsx
/*
Initial items in data:
[{
id: 1,
name: "name",
children: []
}, {
...
}]
`isExpanded` exists only when the sub objects are getting received
*/
export const tableReducer = (state = [], action) => {
switch(action.type) {
case "RCV_OBJECTS":
return action.data;
case "RCV_SUB_OBJECTS": {
const { rowId, subObjects } = action;
const rowIdx = state.findIndex(item => item.id === rowId);
const row = state[rowIdx];
return [
...state.slice(0, rowIdx),
{ ...row, children: subObjects, isExpanded: true },
...state.slice(rowIdx + 1)
];
}
case "UNEXPAND_ROW": {
const { rowId } = action;
const rowIdx = state.findIndex(item => item.id === rowId);
const row = state[rowIdx];
return [
...state.slice(0, rowIdx),
{ ...row, isExpanded: false },
...state.slice(rowIdx + 1)
];
}
}
};
Codesandbox is throwing a SSL error, so can't seem to upload there. Let me know if you need more context.
I have the same issue. Please use the code sandobox. Just use a context menu to select rows and click on the button.
If I go to the new page then rows will be expanded.
Thank you @gnomewoood @sk364 for providing additional details.
This is not necessarily a bug but "was" an intended design. Historically, expandableRowExpanded
was named defaultExpandedRows
and intended to just set default expanded rows on initial render, but I think the name expandableRowExpanded
has evolved to read otherwise and I may have meant to make it work in the way you are attempting. I'll look at prioritizing this feature/fix soon after I do some testing. Unfortunately, there is no workaround until then :(
Internally TableRow
(where row expanded state is managed) uses const [expanded, setExpanded] = useState(defaultExpanded);
to set the initial state:
defaultExpanded
is derived from expandableRowExpanded
The issue with this is the expanded row state can only ever be set at initial render aka defaultExpanded. I believe a useEffect could be used here to make this work.
Ok, should be fixed in 6.4.0 with some caveats:
This is a one-way deal. While this allows you to change the state of the expanded rows and handle cases like expand all/collapse all it will only change the default expanded state. Clicking an individual expander on a row will not change expandableRowExpanded
and the expanded state on your data. You can mess around with onRowExpandToggled
and see if you can reconcile the state.
I realize this may be cumbersome, but the expand row feature was never intended to get into these edge cases. Simply, just allow you to have expandable rows. So, to get all these edge cases to work will require some significant refactor internally of how the expander state is handled. Probably similar to how selectableRows is handled.
It would be good to understand all the cases and the rationale as to why we need programmatic row expansions. I'm aware that we need a expand/collapse all feature, and aside from default expanded rows (when there is a rendering change) I would weigh if this makes the UX better or worse to allow rows to be toggled all over the place.
Issue Check list
styled-components
Describe the bug
DataTable is not expanding the row on row object property change
To Reproduce
Steps to reproduce the behavior:
row => row.expandMe
row.expandMe
to false on initial loadrow.expandMe
to true through button clickExpected behavior
Should expand the row.
Versions (please complete the following information)
Additional context
Expands the row when you change the page and come back.
How do I force re-render the table row?