hmoore
hmoore

Reputation: 165

React/JSX - How to render a list alphabetically

I am working on someone else's code and trying to figure out how to render a list alphabetically in React. I didn't write any of this and have very little knowledge of React, so please bear with me.

The ul looks like this:

<ul className="prod-group__filter__options" ref={(options) => this.options = options}>
    {
        filter.dropdown.map((option, index) => (
            this.renderOption(filter, option, index)
        ))
    }
</ul>

and the renderOption function, which obviously renders the list items looks like this:

renderOption(filter, option, index) {
    return (
        <li className="prod-group__filter__option" key={index}>
            <label className="prod-group__filter__option__label">
                <input name={filter.name}
                       type="checkbox"
                       defaultValue={option.slug}
                       checked={option.checked}
                       onChange={this.optionChangeHandler} />
                {option.label}
            </label>
        </li>
    );
}

The value I am trying to alphabetize is option.slug which is coming from a json list. Can anyone help me get a bit closer to rendering this list alphabetically?

Upvotes: 2

Views: 4359

Answers (3)

hmoore
hmoore

Reputation: 165

In case anyone is interested, the solution was to sort the list items before calling .map() on it as both macbem and finch suggested. I used const to create an "items" constructor that I could then pass into the ul further down:

const items = [].concat(this.props.options)
  .sort((a, b) => {
    const One = a.slug.toUpperCase();
    const Two = b.slug.toUpperCase();

    return (One < Two) ? -1 : (One > Two) ? 1 : 0;
  })
  .map((option, index) => this.renderOption(name, option, index));

return (
  <div className={classes}>
    <a className="prod-group__filter__dropdown"
       ref={(trigger) => this.trigger = trigger}
       onClick={this.triggerClickHandler}>
      {label}
    </a>
    <ul className="prod-group__filter__options" ref={options => this.options = options}>
      { items }
    </ul>
  </div>
);

Upvotes: 0

kimobrian254
kimobrian254

Reputation: 577

You will have to sort option alphabetically using plain javascript before calling filter.dropdown.map... on it. I would advice using lodash function _.sortBy(option, 'slug'); where option is an array of objects with a property called slug then you can pass the sorted result to your map function.

Upvotes: 2

macbem
macbem

Reputation: 1230

It looks like filter.dropdown is your array of options. This array is passed to the .map() method which then runs a renderOption method in the given order.

Hence, you should sort the filter.dropdown array in your ul component code just before calling .map() on it.

Upvotes: 2

Related Questions