1

I have multiple elements that are coming dynamically and the markup is like this:

<li>
    <div>
        <input type="radio" value="abc" name="abc">
        <span>ABC</span>
    </div>
</li>
<li>
    <div>
        <input type="radio" value="bcd" name="bcd">
        <span>BCD</span>
    </div>
</li>

What I need is to sort these elements in react? What would be the best approach here? to sort value or name or span content and how to do so?

Currently I'm mapping them:

const RadioButtonComponent = ({question, setAnswer, answer, lang}) => {

    const radioSingleElement = question.options.map((opt) => {


        return <li onClick={() => setAnswer(option.value)}>
        <Radio className="r-buttons" value={opt.value}} /><span>{question.useKeysForLabels ? lang[opt.label] : opt.label}</span>
        </li>
    });

    return (

        <RadioGroup name={question.name} selectedValue={answer} onChange={(value) => {setAnswer(value);}>
            <ul>
                {radioSingleElement}
            </ul>
        </RadioGroup>

    )
}
3
  • 1
    It depends entirely on what you want to sort them by. I'd assume you want to sort them by <input> value, though that would be a personal opinion, and asking for those would be off-topic for StackOverflow. Commented Nov 28, 2017 at 19:57
  • You said it's coming dynamically so I'm assuming your rendering this html by mapping an array? My suggestion would be to sort the array via javascript then render the array using the .map function. Commented Nov 28, 2017 at 19:58
  • There are many ways to sort elements. You can sort its values and then render HTML content with the ordered values with pure JavaScript. See this question: stackoverflow.com/questions/46923526/…. Commented Nov 28, 2017 at 20:02

2 Answers 2

4

Simply sort and map your options array.

const RadioButtonComponent = ({question, setAnswer, answer, lang}) =>
  <RadioGroup
    name={question.name}
    selectedValue={answer}
    onChange={value => setAnswer(value)}
  >
    <ul>
      {options
        .sort((opt1, opt2) => opt1.label > opt2.label) // order options alphabetically by label
        .map(option =>
          <li key={option.value} onClick={() => setAnswer(option.value)}>
            <Radio
              className="r-buttons"
              value={opt.value}
            />
            <span>{question.useKeysForLabels ? lang[opt.label] : opt.label}</span>
          </li>
        )
      }
    </ul>
  </RadioGroup>
Sign up to request clarification or add additional context in comments.

2 Comments

Can you have a look again at my question? I added how i map them.
@Camila I keep my explanation. Just adapted to your code now :)
2

There are several ways to handle this, but the best way is to sort the array that you're getting the data from. I'm assuming that you want the user to be able to sort the data in ascending/descending order. So, you would have a data array that looks like this:

constructor(props) {
 super(props);

 state = {
  data: [ { name: 'abc', type: 'foo' }, { name: 'bcd', type: 'bar' }, ...],
  sortAscending: true
 }

 this.sortList = this.sortList.bind(this);
}

sortList() {
 let newData = this.state.data.sort((objectA, objectB) => {
  if (this.state.sortAscending) {
   return objectA.name - objectB.name;
  } else {
   return objectB.name - objectA.name;
  }

 this.setState({
  sortAscending: !this.state.sortAscending,
  data: newData
}

render() {
 <button onClick={ this.sortList }>Sort</button>
}

I didn't try that out, but I think you should be able to get that to work if I made a couple of mistakes. Let me know if you have any questions.

6 Comments

I added the whole thing, so can you have one more look at how i'm mapping and how i can include sort there?
I'm a bit unclear what you want here, if all you're asking is how to sort the items before mapping, then just sort like: options = question.options.sort((a,b) => { return b - a; }); then options.map just like you did. Your question.options array is just a regular array, so you sort like any other array.
It's sorting whenever it renders that component and i want it to be rendered only once.
then I suggest you sort the data on the server side, as I don't believe you have an option here. You receive the data, it renders, it then sorts, then you re-render with new state info. The only way to fix this, that I know of, is to sort on the server side, and send the data pre-sorted.
Thank you. I appreciate your replay!
|

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.