There are two things that I am trying to accomplish that I am having trouble with.
First, one of my columns represents more than one value so it can be sorted more than 2 ways. However, the order parameter of the ColumnSortParameters of the sortFunction callback only has 3 values (-1, 0, 1) for ascending, unsorted, and descending. I am able to more or less work around this limitation in the following way.
Assuming I have a functional component that is the container of my DataTable I use a custom hook that is similar to this:
Code: Select all
function useTableData(initialRows) {
const [rows, setRows] = useState(initialRows);
const [orders, setOrders] = useState({});
// Other stuff
const onColumnSort = (params) => {
const field = params.field;
const order = orders?.[field] || 0;
const sortedRows = rows.sort((row1, row2) => {
// getColumnValue(...) gets the appropriate value from the
// column based on the order
const value1 = getColumnValue(field, row1, order);
const value2 = getColumnValue(field, row2, order);
if (a < b) { return -1; }
if (a > b) { return 1; }
return 0;
};
if (isEven(order)) { sortedRows.reverse(); }
const mod = field === "columnWith2Values" ? 4 : 2;
// Note this only works if I modify the object in place. If I try to
// use the setter, I get an error
// that I cannot update a component while rendering a different
// component.
orders[field] = (order + 1) % mod;
return sortedRows;
}
return {rows, onColumnSort};
}
Code: Select all
export default function MyComponent(props) {
const {rows, onColumnSort} = useTableData(props.initialTableRow);
// Other stuff
return (
<DataTable
value={rows}
>
<Column
key="columnWith2Values"
field="columnWith2Values"
header="Header"
body={makeBody()} // Creates the template for displaying the multi valued cell
sortable
sortFunction={onColumnSort}
/>
</DataTable>
);
}
The second question is, how can I dynamically modify the sort icons shown in the column headers? I would like to have a different icon in the header based on the value that is being sorted upon and whether it is ascending or descending. As an alternative, I would be fine with being able to alter the header content when the column is sorted. I've tried storing the dynamic content in a state variable and changing it in the sortFunction, but I run into the same problem as before. Namely, that setting the state causes an error that I cannot update a component while rendering a different component.