0

I'm new to React and I'm trying to sort an array of objects by name is ascending and descending order. I'd also like the sorting to start as soon as the DOM renders hence why I'm using componentDidMount().

The problem I'm having is when you select 'Z - A' option from the dropdown. For some reason the sorting function doesn't work first time then when you select 'A - Z' it's ordering in the opposite order. Any ideas where I'm going wrong? been at this for weeks and I'm completely stumped.

For componentDidMount() are you supposed to call custom functions like that or should I be doing it differently?

Thanks

import React from 'react';
import ReactDOM from 'react-dom';

class App extends React.Component {
    constructor(props) {
        super(props);
        this.updateValue = this.updateValue.bind(this);
        this.sortData = this.sortData.bind(this);
        this.state = {
            people: [
                { name: 'Abi', age: 18 },
                { name: 'Britney', age: 22 },
                { name: 'Carol', age: 52 },
                { name: 'Danni', age: 17 },
            ],
            sortBy: 'AZ'
        }
    }
    sortData() {
        if (this.state.sortBy === 'AZ') {
            this.setState((prevState) => {
                return {
                    people: prevState.people.sort((a, b) => a.name > b.name ? 1 : -1)
                }
            });
        }
        else if (this.state.sortBy === 'ZA') {
            this.setState((prevState) => {
                return {
                    people: prevState.people.sort((a, b) => b.name > a.name ? 1 : -1)
                }
            });
        }
    }
    updateValue(event) {
        const value = event.target.value;
        console.log(value);

        this.setState(() => {
            return {
                sortBy: value
            }
        });

        this.sortData();
    }
    componentDidMount() {
        this.sortData();
    }
    render() {
        return (
            <div>
                <p>{ this.state.sortBy }</p>
                <select value={ this.state.sortBy } onChange={ this.updateValue }>
                    <option value="AZ">A - Z</option>
                    <option value="ZA">Z - A</option>
                </select>
                <ul>
                    { this.state.people.map((person) => <li key={person.name}>{ person.name }</li>) }
                </ul>
            </div>
        );
    }
};

const root = document.querySelector('#appRoot');

ReactDOM.render(<App/>, root);

2 Answers 2

1

I have improved your code. Try this

import "./styles.css";
import React, { Component } from "react";
export default class App extends Component {
  state = {
    people: [
      { name: "Abi", age: 18 },
      { name: "Britney", age: 22 },
      { name: "Carol", age: 52 },
      { name: "Danni", age: 17 }
    ],
    sortBy: "AZ"
  };
  sortData = (value) => {
    if (value === "ZA") {
      this.setState((prevState) => ({
        people: prevState.people.sort((a, b) => (b.name > a.name ? 1 : -1))
      }));
    } else if (value === "AZ") {
      this.setState((prevState) => ({
        people: prevState.people.sort((a, b) => (a.name > b.name ? 1 : -1))
      }));
    }
  };
  updateValue = (event) => {
    const { value } = event.target;
    this.setState(() => ({ sortBy: value }));
    this.sortData(value);
  };
  componentDidMount() {
    this.sortData();
  }
  render() {
    const { sortBy, people } = this.state;
    return (
      <div>
        <p>{sortBy}</p>
        <select value={sortBy} onChange={this.updateValue}>
          <option value="AZ">A - Z</option>
          <option value="ZA">Z - A</option>
        </select>
        <ul>
          {people.map((person) => (
            <li key={person.name}>{person.name}</li>
          ))}
        </ul>
      </div>
    );
  }
}

Live working demo

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

Comments

1

Use it like this, your state is updating after sorting that's why you are seeing sorting in wrong order.

updateValue(event) {
    const value = event.target.value;
    console.log(value);

    this.setState({sortBy: value},()=>{
      this.sortData();
    });
}

Comments

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.