Reputation: 349
I'm trying to handle a sort function that toggles between dsc and asc. It also needs to handle a certain table column name which is referred to as "header". The expected outcome is to sort either "days" or "station" and have it toggle separately between dsc and asc.
handleClick={(val: any, header: string) =>
val((val: any) => {
const result = [...val].sort((a: any, b: any) => {
return sortOrder === 'asc'
? header === 'Station'
? b.station - a.station
: b.days - a.days
: header === 'Station'
? a.station - b.station
: a.days - b.days;
});
setSortOrder(sortOrder === 'asc' ? 'dsc' : 'asc');
return result;
})
}
This is my current function station filters properly but "Days Since Last Event" doesn't seem to work.
This is the handleClick on the child function
onClick={() => props.handleClick(setFilteredData, header)}
This is the sample of the data
[
{
days: 23,
station: "Braidwood",
},
{
days: 18,
station: "Byron",
},
{
days: 28,
station: "Byron",
},
{
days: 32,
station: "Calvert Cliffs",
},
{
days: 20,
station: "Dresden",
},
{
days: 320,
station: "Dresden",
},
];
Upvotes: 1
Views: 156
Reputation: 202618
As-written, your handler sorts a copy of the filteredData
and then toggles the sorting order. This means the actual order is always inverted from the current sortOrder
state.
If I had to guess, I would say the onClick
handler is supposed to toggle the sorting order, and then you want the filteredData
state to be resorted.
The onClick
handler should toggle the state, and the resorting can be done in an useEffect
hook with a dependency on the sortOrder
and header
state.
React.useEffect(() => {
setFilteredData(data => data.slice().sort((a: any, b: any) => {
return sortOrder === 'asc'
? header === 'Station'
? b.station - a.station
: b.days - a.days
: header === 'Station'
? a.station - b.station
: a.days - b.days;
}));
}, [header, sortOrder]);
const toggleSortOrder = (header: string) => () => {
setSortOrder(sortOrder === 'asc' ? 'dsc' : 'asc');
setSortHeader(header);
};
...
handleClick={toggleSortOrder(header)}
Additionally, since the ascending/descending functionality is basically the same, I'd suggest converting the sort comparator into a higher order function that swaps the inputs and return a simpler comparator function.
const customSort = (sortOrder = 'asc', header = 'Station') => {
const comparator = (a: any, b: any) => header === 'Station'
? b.station - a.station
: b.days - a.days;
return sortOrder === 'asc' ? comparator : (a, b) => comparator(b, a);
}
React.useEffect(() => {
setFilteredData(data => data.slice().sort(customSort(sortOrder, header)));
}, [header, sortOrder]);
Upvotes: 1