'The clicked column header cannot be determined correctly
I'm new to ReactJS. I have a table with 2 columns. I want to sort the table based on the column header that is clicked on. Here is the code:
import React, { useState, useEffect } from 'react'
import { getUsers } from '../../services/userService'
const Table = () => {
const [users, setUsers] = useState([]);
const [currentUsers, setCurrentUsers] = useState([]);
const [isSorted, setIsSorted] = useState(false);
const [valueHeader, setValueHeader] = useState({title: "",body: ""}); //Value header state
const [sortedUsers, setSortedUsers] = useState([]);
useEffect(async () => {
try {
const response = await getUsers(search);
setUsers(response.data.users);
} catch (error) { }
}, [search]);
const sortFn = (userA, userB) => {
// sort logic here, it can be whatever is needed
// sorting alphabetically by `first_name` in this case
return userA[valueHeader.body].localeCompare(userB[valueHeader.body]) //<== Use value of culumn header
}
useEffect(() => {
if (isSorted) {
setSortedUsers(currentUsers.slice().sort(sortFn))
} else {
setSortedUsers(currentUsers)
}
}, [isSorted, currentUsers, valueHeader]) //<== add valueHeader to dependency
const toggleSort = ({target}) => {
setIsSorted(!isSorted)
setValueHeader({
title: target.value,
body: target.value == "name" ? "first_name" : "mobile_number"
}) //<=== set state of value header
}
return (
<div dir='rtl' className='bg-background mt-10 px-5 rd1200:px-30 overflow-auto'>
<table className='w-full border-separate rounded-md'>
<thead>
<tr className='bg-text-secondary text-white shadow-sm text-center'>
<th className='p-2' onClick={toggleSort}>name</th>
<th className='p-2' onClick={toggleSort}>mobile</th>
</tr>
</thead>
<tbody>
{sortedUsers.map((item, index) =>
<tr key={item.id} className={index % 2 === 0 ? 'bg-white shadow-sm text-center' : 'bg-text bg-opacity-5 shadow-sm text-center'}>
<td className='text-text text-sm p-2'>{item.first_name}</td>
<td className='text-text text-sm p-2'>{item.mobile_number}</td>
</tr>
)}
</tbody>
</table>
</div>
)
}
export default Table
The problem is that regardless of which column I click on, the table is only sorted based on the mobile column. I tried to find the problem, it seems that even after clicking on a column header, the value of target.value becomes undefined and as a result, even when I click on name column, the value of valueHeader.body becomes mobile based on the logic used in the toggleSort function, so the table is sorted based on mobile column. How can I solve this?
Solution 1:[1]
Just add to this line, mainAxisAlignment: MainAxisAlignment.end
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Container(
child: Text("Hello world"),
height: 100.0,
width: 100.0,
color: Colors.blueAccent,
),
Container(
child: Text("Hello World"),
height: 100.0,
width: 100.0,
color: Colors.greenAccent,
),
Container(
child: Text("Hello World"),
height: 100.0,
width: 100.0,
color: Colors.amberAccent,
),
],
)
Solution 2:[2]
put mainAxisAlignment: MainAxisAlignment.end inside row
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Poran |
| Solution 2 | Rintu Banerjee |
