Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: Persist the scroll position and prevent reload on navigating back #4

Closed
FrozenHearth opened this issue Nov 14, 2022 · 8 comments
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@FrozenHearth
Copy link

First of all, fantastic project! Really looks like Twitter.

As the title says, if you notice Twitter, it persists your scroll position when you navigate back, and I guess doesn't call the fetch tweets API again if there are no new tweets, due to which the navigation feels instant.

I don't know the complexity that would be involved in such a task, but I feel it would be a great addition to this project.

@ccrsxx
Copy link
Owner

ccrsxx commented Nov 15, 2022

Now that you mention it, I just realized that Twitter saved the scroll position on each page, that's pretty cool I'd say.

According to this answer on Stack Overflow, the solution is pretty simple. You just need to save the scroll position on the local storage on each page whenever the route changes, and when you get back to the route with the saved scroll position, you apply the saved scroll position to its route.

I can make a hook for this functionality and use it for each route. But the problem is caching the tweets, it'd feel weird when you get to your scroll position and see nothing because the data is still loading (not cached).

I don't know how to cache data in Firestore. I bet that'd require me to change many codes for getting the tweets. Before I implement this feature, I need to think about how to cache the tweets.

I'm open to any pull requests if you want to help me with this feature. I'll be happy to review your code and merge it into the project.

@ccrsxx ccrsxx added enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers labels Nov 15, 2022
@rajdeep-ghosh
Copy link

@ccrsxx You can use the react-query package. It takes care of caching, garbage collection of stale data, scroll restoration, refetching automatically.

You can mimic the firestore data fetching as an API and instead of returning the data return a Promise (it requires it).

And once again this project is amazing. I'm sure I will learn a lot from this project. Great work 👍

@ccrsxx
Copy link
Owner

ccrsxx commented Nov 15, 2022

@rajdeep-ghosh I'd prefer not to add another dependency to this project. Not to mention I've never used that library. I'm using SWR to fetch Trending data from Twitter API. Maybe this library could do the same?

@rajdeep-ghosh
Copy link

Yes SWR can also do the same as react-query. They are almost identical.

@FrozenHearth
Copy link
Author

FrozenHearth commented Nov 15, 2022

Now that you mention it, I just realized that Twitter saved the scroll position on each page, that's pretty cool I'd say.

According to this answer on Stack Overflow, the solution is pretty simple. You just need to save the scroll position on the local storage on each page whenever the route changes, and when you get back to the route with the saved scroll position, you apply the saved scroll position to its route.

I can make a hook for this functionality and use it for each route. But the problem is caching the tweets, it'd feel weird when you get to your scroll position and see nothing because the data is still loading (not cached).

I don't know how to cache data in Firestore. I bet that'd require me to change many codes for getting the tweets. Before I implement this feature, I need to think about how to cache the tweets.

I'm open to any pull requests if you want to help me with this feature. I'll be happy to review your code and merge it into the project.

I was thinking more along the lines of this: https://v5.reactrouter.com/web/guides/scroll-restoration
Wherein, you restore the previous scroll position on back/forward button click.

For one of my unfinished personal projects, I was able to cache the component data by checking if there's data in the redux store. If there is data, I don't make the API call again on component mount.

https://github.com/FrozenHearth/TmDB/blob/46dd80345ddb242da728b8e6c4176d58d124f8db/src/pages/MovieDetails.js

The limitation with this is that you don't know if the data is stale. I think this is where SWR could come handy.
I'm unfamiliar with Next.js(need to learn it), but this seems like a fun and challenging task to tackle. I'll try to see if I can come up with a solution for this.
Meanwhile, anyone else is also free to try. Always open to learning from people. :)

@trenom-id
Copy link

I see that you are using Next JS for this project, maybe you could try adding the following code to the next.config.js file to implement scroll restoration (I used this on Next version 12.2.3, I don't know if it will work on the later versions) :

const nextConfig = {
	...
	experimental: {
		scrollRestoration: true
	}
};

And to prevent stale data when user gets to his/her previous scroll position, I believe useSWR() does revalidate automatically on component mount (source: https://swr.vercel.app/docs/revalidation).

@ccrsxx
Copy link
Owner

ccrsxx commented Jan 25, 2023

@codingtiktok hmm, I didn't know about that config. Could probably solve the scroll position, but the problem is the data.

Yes, useSWR does revalidate the data when the component mount again. The problem is that I use the Firebase SDK to fetch the data from the Firestore, so I can't use the SWR here to cache the data here.

I only use SWR to fetch the Trending from Twitter API and refresh it every 30 seconds.

@ccrsxx
Copy link
Owner

ccrsxx commented Jan 25, 2023

I'll rewrite this project in the future using MongoDB and express after I learn Backend.

Hopefully, I'll be able to implement this feature as well as improve the current codebase performance.

I'm closing this issue now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants