0

I have an array that looks similar to this

const chapters= [
   { index:1, title:'chapter-1', lessons:[] }
   { index:2, title:'chapter-2', lessons:[] }
   { index:3, title:'chapter-3', lessons:[] }
]

And this comes already sorted from backend on the basis of index
Now I want to create a state of chapters array in react by this approach

chapters.forEach(chapter=>{
   this.setState((prevState) => {
            return {
              ...prevState,
              chapters: [
                ...prevState.chapters,
                {
                  chapterTitle: chapter.title,
                  chapterIndex: chapter.index,
                  lessons,
                },
              ],
            };
          });
});


the problem is the state is not sorted. I even tried to sort the states after they have been written once. For that I follwed this code i found in stackoverflow

const sortedChapters= this.state.chapters.sort((a, b) =>
            a.index > b.index ? 1 : b.index > a.index ? -1 : 0
          );
this.setState({ chapters: sortedChapters});

But no luck. please tell me what I am doing wrong here?

3
  • 1
    I can't explain why it isn't retaining the order from your API call, but sort does mutate the original array. So your setState is probably not triggering a re-render. This could be part of your problem. Commented Jun 5, 2020 at 19:10
  • 1
    I tried using for loop instead of foreach loop,and it works fine,can you explain why this happens? Commented Jun 5, 2020 at 19:12
  • 1
    And is there any way I can stick to forEach because it seems faster than for loop Commented Jun 5, 2020 at 19:14

1 Answer 1

4

You should almost never set state in a forEach loop. Try this:

const chaptersFromBackend = [
   { index:1, title:'chapter-1', lessons:[] }
   { index:2, title:'chapter-2', lessons:[] }
   { index:3, title:'chapter-3', lessons:[] }
];

const chaptersFormatted = chaptersFromBackend.map(chapter => {
   return {chapterTitle: chapter.title, chapterIndex: chapter.index, lessons: chapter.lessons};
});

this.setState({chapters: chaptersFormatted});

Because of the way react works, the last line wont mess with any other properties you have in your state. I.e. state.foo will be untouched.

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

1 Comment

This is a much better approach than calling multiple setStates

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.