2

I am building a simple app in ReactJS that works with a JSON array by calling a certain API. I am then populating the results of the array in a table. I now wanted to make the columns of the table sortable. What I ideally want is to have both ascending and descending sorting. Once I click on the header when it is sorted ascending, it should sort descending and vice-versa. Here is my code.

class ParentComponent extends Component {
constructor(props) {
 super(props);
 this.state = { data: [] };
}

componentDidMount() {
  fetch("http://hostname:xxxx/yyyy/zzzz")
  .then(function(response) {
    return response.json();
  })
  .then(items => this.setState({ data: items }));
 }

render() {
var newdata = this.state.data;

return (
  <table className="m-table">
    <thead>
      <tr>
        <th>AccountName</th>
        <th>ContractValue</th>
      </tr>
    </thead>
    <tbody>
      {newdata.map(function(account, index) {
        return (
          <tr key={index} data-item={account}>
            <td data-title="Account">{account.accountname}</td>
            <td data-title="Value">{account.negotiatedcontractvalue}</td>
          </tr>
        );
      })}
    </tbody>
  </table>
  );
 }
}

export default ParentComponent;

1 Answer 1

15

You can add a sort property to your state with column and direction properties:

state = {
  data: [],
  sort: {
    column: null,
    direction: 'desc',
  },
};

Of course you should also have a sort handler like so:

onSort = (column) => (e) => {
  const direction = this.state.sort.column ? (this.state.sort.direction === 'asc' ? 'desc' : 'asc') : 'desc';
  const sortedData = this.state.data.sort((a, b) => {
    if (column === 'accountName') {
      const nameA = a.accountName.toUpperCase(); // ignore upper and lowercase
      const nameB = b.accountName.toUpperCase(); // ignore upper and lowercase
      if (nameA < nameB) {
        return -1;
      }
      if (nameA > nameB) {
        return 1;
      }

      // names must be equal
      return 0;
    } else {
      return a.contractValue - b.contractValue;
    }
  });

  if (direction === 'desc') {
    sortedData.reverse();
  }

  this.setState({
    data: sortedData,
    sort: {
      column,
      direction,
    }
  });
};

I got the sorting from MDN.

Here's a sample pen: https://codepen.io/anon/pen/xrGJKv

Sign up to request clarification or add additional context in comments.

6 Comments

Great stuff !! Is it possible to use the regular function in place of arrow function
@MidhunMathewSunny yes it is. but you need to bind this to that function in order for it to work in the tags. Here's a link on how you can bind this in different ways: medium.freecodecamp.com/…
could you show me in codepen how to do it without using arrow functions. i tried, but couldnt succeed.
Thanks a lot. Just 1 thing. The arrow in the header column is not getting displayed for me. What can be the reason for that
It's probably the same issue with fat arrow functions.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.