-3

I have multiple components, but only two are relevant to this question - FrontPage and Stream.

At the beginning of FrontPage, I have a useEffect in which I fetch all the posts from the server, and put them inside postsArray, which I then send as prop to the Stream component.

At the bottom of the frontPage component, I do pagination by slicing the postsArray, and creating a new array called 'currentPosts', which I also send as prop to the 'Stream' component. While doing so, I also reverse the order of the posts, and this is where I am having trouble understanding something.

When I reverse the order BEFORE I assign the sliced array to currentPosts, the order is not reversed. But if I do it afterwards, it works.

 let currentPosts = [];
   if(postsArray.length !== 0) { 
        console.log('here')
        //postsArray.reverse()
        currentPosts = postsArray.slice(indexOfFirstPost, indexOfLastPost)
        postsArray.reverse()
   }

This is the relevant part of the code. If the reverse is done before the assignment to currentPosts, the reverse does not work. If it's done right after it, it works. I don't understand why.

If I do the reverse before I slice and assign it to currentPosts, if I then console log the currentPosts and postsArray right before rendering the frontPage component, and right before rendering the Stream component, the console log shows that in the frontPage component, the currentPosts array is not reversed, but in the Stream component, it is reversed, but postsArray is not.

How could this be?

If I do the reverse() after the slicing, then both currentPosts and postsArray are not reversed in both components.

I was thinking that perhaps it takes time for the reverse() is finish executing, and that's why the array is consoled out not reversed right before rendering the frontPage component, but then, once the reverse() has finished executing, how does that overwrites the already assigned currentPosts array in the Stream component, and if that's really what's happening, then why does it not overwrite the postsArray too?

Here's a snapshot of the console log.

enter image description here

happy_story
  • 1
  • 1
  • 7
  • 17
  • Hi! Please update your question with a [mcve] demonstrating the problem, ideally a **runnable** one using Stack Snippets (the `[<>]` toolbar button). Stack Snippets support React, including JSX; [here's how to do one](http://meta.stackoverflow.com/questions/338537/). – T.J. Crowder Dec 14 '21 at 16:52
  • @T.J.Crowder That's completely impossible, and unnecessary. My question is rather about theory, not practical problem. I want to know why it work when it's defined AFTER, but not BEFORE the slice. – happy_story Dec 14 '21 at 17:27
  • 1
    No, it's not impossible to demonstrate the client-side, React thing you're asking about, please read through the [provided link](/help/minimal-reproducible-example). No, it probably isn't (just) theoretical, it's probably something to do with the code. So show us the code. But even if it **were** completely theoretical, the code (including initial conditions) helps us understand what's happening and thus, help you understand it. – T.J. Crowder Dec 14 '21 at 17:30
  • The only possible explanation I can think of is something related to the States and that it takes times for the array to get reversed, which means the rest of the code continues, and then when the reversing is done, since a reference of the array is used in assigning the `currentPosts`, likely that's why even later when the reversing is done, the `currentPosts` in the `Stream` component are reversed, but not in `frontPage` before rendering. I am still unsure why then is `postsArray` itself not reversed in either component.. – happy_story Dec 14 '21 at 19:54
  • Also in my defense, I do intent on cleaning the code a bit.. I usually do that once I am done with the functionality. – happy_story Dec 14 '21 at 19:56
  • *"How can I show you only the client side when the postsArray in question is populated with posts fetched from the server, my server"* So, you clearly haven't read the provided links (in particular [this one](http://meta.stackoverflow.com/questions/338537/)), which cover that. – T.J. Crowder Dec 15 '21 at 06:46

1 Answers1

1

One option is to explicitly set postsArray equal to the reversed array.

let currentPosts = [];
if(postsArray.length !== 0) { 
   console.log('here')
   postsArray = postsArray.slice().reverse()
   currentPosts = postsArray.slice(indexOfFirstPost, indexOfLastPost)
   postsArray.reverse()
}

It's daft, but it works

Andrew Corrigan
  • 1,017
  • 6
  • 23
  • I think you misunderstand my question. I am asking why does it WORK when it's AFTER the slice, but does not work when it's BEFORE the slice. I just want to understand why one works but the other does not? This must be an issue with the order of invocation, or something like that. – happy_story Dec 14 '21 at 17:26
  • Does it work if you put a setTimeout around the first reverse call? If so it's likely the async nature of JS - doing the slice works because it's just copying the array to a new one. – Andrew Corrigan Dec 15 '21 at 08:34
  • I tried timeout just now, but it's not working either. It's so bizarre. I also tried putting the slicing part in a timeout to ensure that the `postsArray` its slicing is already reversed, but it's not working. I consoled out the `postsArray` inside the timeout, and it still shows that it's not reversed inside. I also noticed that for some reason the timeout is invoked twice. I have no idea why. I thought it could be because the `postsArray` is a state, and reversing the objects inside could be seen as changing the state thus causing a render, but that's not it. I am completely lost. Any ideas? – happy_story Dec 15 '21 at 12:44
  • The only thing I can think is maybe it's to do with how `postsArray` is defined - if postsArray isn't defined as a static array (i.e. like `currentPosts` is) then maybe it's doing something weird based on what it thinks `postsArray` should be? See if the same code works on an explicitly defined array? – Andrew Corrigan Dec 15 '21 at 12:58
  • Yeah, I was thinking something similar. Perhaps because `postsArray` is a state, reversing it does not technically update the state, and that's why even after 1 sec timeout, the `postsArray` is still not reversed, because the state has not been updated. However that still does not explain why reversing it AFTER the slicing works, but not BEFORE the slicing. I wonder if this is some peculiarity in the nature of React, or if it's something fundamental that I just don't know. Maybe when it's done BEFORE slicing, the state is altered in a different way than when it's done AFTER the slicing. – happy_story Dec 15 '21 at 13:26
  • 1
    Okay, so I just tried what you said, and I got an interesting result. I created a new array right next to `let currentPosts = []`, and I extracted the `postsArray` inside. Then inside the `if` condition, when I reverse the new array, which I called `regularPostsArray`, when I reversed it AFTER the slicing, it didn't work, but now it works when I reverse it BEFORE the slicing. So I am getting the opposite outcome. So, this kind of makes a bit more sense now, right? It makes sense to work BEFORE slicing it, not after it. So, this proves that the issue has to do with the state? – happy_story Dec 15 '21 at 13:32
  • Yeah, that makes more sense and is probably the answer. Granted, I'm surprised that it didn't work after the slice - was expecting it to work regardless of the slice in a fresh array. – Andrew Corrigan Dec 15 '21 at 13:53
  • 1
    Reversing it after slicing works in the sense that it's consoled out reversed before rendering, but the `currentPosts` are not reversed, because the new posts array `regularPostsArray` is sliced and assigned to `currentPosts` BEFORE the `regularPostsArray` is reversed. When it's reversed later, `currentPosts` is already assigned. So to me it makes sense that `currentPosts` is not reversed. I still don't understand why reversing the `postsArray` state before and after slicing makes a difference, but at least now I know it has to do with the array being a state. I guess I'm content with this. – happy_story Dec 15 '21 at 14:16