It’s better to use the setState overload that takes a function instead of the object.
Here is a simple example.
class Sample extends React.Component {
constructor() {
super();
this.initData = [
{name: 'John', family: 'Doe'},
{name: 'Jane', family: 'Hardy'}
];
this.state = {
sortField: 'name',
sortOrder: 'asc',
data: this.initData
};
}
sort(column) {
this.setState(prevState => {
if (prevState.sortField === column) {
const sortOrder = prevState.sortOrder === 'asc' ? 'desc' : 'asc';
return {
sortOrder,
data: [...prevState.data].sort((a, b) => {
const textA = a[column].toUpperCase();
const textB = b[column].toUpperCase();
if (sortOrder === 'asc') {
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
}
else {
return (textA > textB) ? -1 : (textA < textB) ? 1 : 0;
}
})
}
}
else {
return {
sortOrder: 'asc',
sortField: column,
data: [...prevState.data].sort((a, b) => {
const textA = a[column].toUpperCase();
const textB = b[column].toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
})
}
}
})
}
render() {
return (
<table>
<thead>
<th onClick={() => this.sort('name')}>Name</th>
<th onClick={() => this.sort('family')}>Family</th>
</thead>
<tbody>
{
this.state.data.map(({name, family}, i) => {
console.log(name, family)
return (
<tr key={i}>
<td>{name}</td>
<td>{family}</td>
</tr>
)
})
}
</tbody>
</table>
)
}
}
React.render(<Sample />, document.getElementById('app'));