Today I gave Hacker Rank's React Basics Challenge. It was a simultaneous actively of attempting it and pulling my hair out in the second question, as to why the F**K is sorting not working? Thankfully, I remembered JIT as to what I was doing wrong. And so, here I am writing this article to tell you what I was doing wrong.
Let's start with the question first. It was simple sorting feature implementation on button clicks. The default article structure was something similar like this:
This was passed into <App /> as props and then from their to <Articles /> as props. So far so good. The sorting buttons were in <App />. On click, some sorting must occur based on the question's logic. In the below image, Assume that <Articles /> is being passed a prop of articles rather than being looped directly.
So, did you find the issue with the above code? If you have, congratulations! Your basics of JS & React is clear. Regardless, keep on reading to tell me if I am wrong!
As I was wondering what is happening, I noticed that JS sort method doesn't need a new variable to store the sorted result. You can do it but it isn't required. That means it is modifying the original array. This seemed to me the simple case of in-place sorting I learned about while doing CSE.
So, what is in-place sorting? In simple terms, it's when you sort an array [apply algorithm] without requiring additional space in memory, and thus modifying the data in the same memory address.
Arrays are also Objects in JS. Therefore, they are copied the same way as well. Primitive data types are copied in the "correct" manner. Meaning, when we copy something, we want a ditto of the "original" with the ability to change the "copy" without affecting "original".
One way is to use the modern JS spread operator. But that won't work in nested object case of ours. It will create shallow copies of 3 objects of dog inside the array of dogs. So, here's a quick solution. JSON.parse() can be used to fix this but know that it won't work for class methods and instances.
So, what was the issue with our initial code? It's how react "reacts" to state changes. More importantly, in functional programming paradigm, it's good and often mandated to not change the existing data. Immutability. React uses Object.is for comparing, comparing the pointers/reference.
Therefore, in our case, the issue was that the original object "articles" is getting mutated by the JS sort() method. This stops the React from 're-rendering' the component. When "sort" button is clicked, the articles object changes. This can be checked by saving the file again to let the hot-reload take its effect and then check the browser display to confirm. Order would have been changed. But then it doesn't re-render due to in-place sorting which mutates the original articles object. The fundamental here is that objects should be immutable for React to re-render the component.
So how did I fix it? I used flag to re-render the component as below.
This way, when the button is clicked, the "f" flag variable gets changed and this in-effect re-renders the <App /> and thus working as needed.