My issue similar to this, but not the same.
I'm trying to sort an array of objects using localeCompare
. It has no reason not to work, but it's not working. Somehow I'm doing something right./sigh/
This is how I fetch the data
const [data, setData] = useState([]);
const [isBusy, setBusy] = useState(true)
useEffect(() => {
console.log('I was run once');
async function fetchData() {
const url = `${
process.env.REACT_APP_API_BASE
}/api/v1/endpoint/`;
axios.get(url).then((response: any) => {
setBusy(false);
setData(response.data.results)
console.log(response.data.results);
});
}
fetchData();
}, [])
This is the sorting function
function onSort(event: any, sortKey: string) {
const newData = data;
newData.sort((a: any, b: any): any => {
a[sortKey].toString().localeCompare(b[sortKey]);
})
setData(newData);
}
A typical array of objects is like this
[
{
"avatar": "big",
"name": "Username",
},
{
"avatar": "small",
"name": "Rex",
},
{
"avatar": "medium",
"name": "Duh",
}
]
Then the table header has this
<th scope="col" className="text-center" onClick={e => onSort(e, 'name')}>Name</th>
Although the onSort()
function runs without any errors, the objects don't get sorted as per the sortKey
Am I using the localeCompare
wrongly? What can I do to make the above right?
Also, the setData
, I believe should update the data
and thus trigger a rebuild of the table, which seems to be happening, because if I pass in an empty array to the setData
, the table blanks.
edit:
The HTML part
...
return (
<div>
<table className="table table-hover">
<thead>
<tr>
<th onClick={e => onSort(e, 'avatar')}>Avatar</th>
<th onClick={e => onSort(e, 'name')}>Name</th>
</thead>
<tbody>
{data && data.map((item: any, index: any) => {
return (
<tr key={index}>
<th>{{ item.avatar}}</th>
<td>{item.name}</td>
<td className="text-center" style={{ 'fontSize': '32px', 'color': '#981c1e' }}>0</td>
</tr>
)
})}
</tbody>
</table>
</div>
...
If I understand, if the setData
triggers a data change, the render
re-renders?