2

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?

1

3 Answers 3

2

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.

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

Comments

2

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.

2 Comments

Thanks finch! Can you possibly give me an example? Since the slug (or value) is only a part of the list item how do I render the full list items alphabetized and not just a list of alphabetized slugs?
Here's a codepen sorting and mapping names and cities. More info on lodash _sortBy
0

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> ); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.