Reputation: 55
i am created table using array of objects and now i didnot undestand How We sort table in ascending and descnding order by clicking on column name in reactjs. I am tried lot of concepts on stackoverflow but it seems it doesnot useful for this one. This is very silly question but I am stopped on this from many days.
class Hello extends Component {
constructor(props) {
super(props)
this.state = {
search: '',
Data:[
{
id: 1,
fullName: 'abc',
email:'[email protected]',
},
{
id: 2,
fullName: 'qps',
email:'[email protected]',
},
{
id: 3,
fullName: 'qwe',
email:'[email protected]',
},
]
}
}
function Sort(){
//what need to write here;
}
render() {
return (
<div>
<h1>welcome to React</h1>
<table className="table table-hover table-dark">
<tbody>
<tr>
<th onChange={this.Sort.bind(this)}>ID</th>
<th>Full Name</th>
<th>Email</th>
</tr>
{
this.state.Data.map((item,index)=>(
<tr key={item.id}>
<td >{item.id}</td>
<td >{item.fullName}</td>
<td>{item.email}</td>
</tr>
))
}
</tbody>
</table>
</div>
)
}
}
export default Hello
Upvotes: 1
Views: 3004
Reputation: 1217
onChange
handler to onClick
.sort()
method, but take care not to mutate your state. this.state = {
order: 'ASC'
...
function sort() {
let sortedList = [...this.state.Data];
let newOrder = this.state.order === 'ASC' ? 'DESC' : 'ASC';
if (newOrder === 'ASC') {
sortedList.sort((a, b) => a.id - b.id)
} else {
sortedList.sort((a, b) => b.id - a.id)
}
this.setState({ Data: sortedList, order: newOrder });
}
To be able to sort on any of the columns, I would make the following change:
function sort(column) {
const sortedList = [...this.state.Data];
const newOrder = this.state.order === "ASC" ? "DESC" : "ASC";
const sortValue = (v1, v2) => {
if (column === 'id') return v1.id - v2.id;
return (v1[column] ?? '')
.toLowerCase()
.localeCompare((v2[column] ?? '').toLowerCase())
}
if (newOrder === "ASC") {
sortedList.sort((a, b) => sortValue(a, b));
} else {
sortedList.sort((a, b) => sortValue(b, a));
}
this.setState({ Data: sortedList, order: newOrder });
}
And add an appropriate onClick
handler for each column heading.
<th onClick={() => this.sort('id')}>ID</th>
<th onClick={() => this.sort('fullName')}>Full Name</th>
<th onClick={() => this.sort('email')}>Email</th>
Upvotes: 2
Reputation: 2422
Add a state variable for ascending or descending sort and then in your sort function:
function Sort(a,b){
if(this.state.ascending){
return a.id - b.id
{
return b.id - a.id
}
And then in your render function add the sort method before the map:
const Data = [...this.state.Data]
//...
Data.sort((a,b)=>this.Sort(a,b)).map((item,index)=>(
<tr key={item.id}>
<td >{item.id}</td>
<td >{item.fullName}</td>
<td>{item.email}</td>
</tr>
Finally change your onClick to just change the state of ascending/descending:
<th onClick={()=>this.setState({ascending: !this.state.ascending)}>ID</th>
Upvotes: 0