You're probably feeling it's faster because it's using <Link prefetch> on every link so everything is prefetched before you click the link (when you hover them) which makes the navigation almost instant once you click it.
Remix has a ScrollRestoration component to handle the scroll position when going back and forward in the browser history.
When you click the browser back button as far as I remember Remix will do what the browsers do and show the previous data, but if you click a button in the UI to navigate to the previous page it will fetch the new data.
Re global state, in my experience with Remix and before it with tools like React Query, once you move the server state (data fetched from an API or queried from a DB) outside tools like Redux, then what you have left is mostly UI state (input values, open/close states, etc.) and you don't need Redux for that.
And if your app is more complex (like a canvas-like app for example) you can either use a state + context in a parent component or you can use Redux or any other state management library, Remix once JS load will not cause a full page navigation so if you initialize a global state in something like Remix it will keep working across page navigations, even if you click back it will keep the state because Remix uses RR to navigate so it's pure client-side navigation.
> When you click the browser back button as far as I remember Remix will do what the browsers do and show the previous data, but if you click a button in the UI to navigate to the previous page it will fetch the new data.
In this news site example the "previous data" was fetched with infinite scroll, and it was lost from memory when the user navigated to the new page. So when the user clicks back in their browser, the browser is unable to show the previous data, because it does not have the previous data in memory any more.
> Re global state, in my experience with Remix and before it with tools like React Query, once you move the server state (data fetched from an API or queried from a DB) outside tools like Redux, then what you have left is mostly UI state (input values, open/close states, etc.) and you don't need Redux for that.
> And if your app is more complex (like a canvas-like app for example) you can either use a state + context in a parent component or you can use Redux or any other state management library, Remix once JS load will not cause a full page navigation so if you initialize a global state in something like Remix it will keep working across page navigations, even if you click back it will keep the state because Remix uses RR to navigate so it's pure client-side navigation.
All this sounds like typical state management in any React app: keep local UI state in React components (no need need for a state management library) and use a state management library to maintain global state.
Your README gave the impression that Remix leverages web fundamentals in a way that removes/reduces the need for a state management library, but based on this discussion it sounds like that is not the case. Thanks for your answers and sorry about hijacking this thread for this.
To answer this question - There is nothing stopping you from fetching on the client still while using remix or from for example wrapping your app with a provider where you can store cached client side data.
Page transitions happen on the client when you have JS enabled so that data will still be in memory if done as such.
But I do want to mention that the specific use case you mention is not what 80%+ of apps are doing and I think you're being a bit unfair. Remix ABSOLUTELY does get rid of most needs for a client side state management solution. Most apps are fetching data and displaying it primarily on page load/route transitions. Or for instance on query param change for paginated data. This is the use case Remix targets, and it does a fantastic job of simplifying the code for this and making it much faster.
For those cases where you really do need to do client side data fetching you are free to do so.
> Remix ABSOLUTELY does get rid of most needs for a client side state management solution. Most apps are fetching data and displaying it primarily on page load/route transitions. Or for instance on query param change for paginated data. This is the use case Remix targets, and it does a fantastic job of simplifying the code for this and making it much faster.
But do these use cases require a state management library in the first place? Can you provide an example where using React Component state is not sufficient - a state management library is needed - and then Remix removes this need?
Remix co-author here. Infinite scroll/pagination is a great way to test the limits of a web framework!
Remix doesn't ship an infinite scroll/pagination set of components so it's up to apps to make sure that state is still there when the user clicks back. If the state is still there, Remix's scroll restoration will work.
You could either manage your own global state for this, but I like to use "location state" which is our API into the browser's built in `history.state`.
There are various ways to use it (declaratively, imperatively, etc.), but simplest way to explain is to imagine a "Load more" button that's really just a link like this:
`<Link to="?page=2" state={{ data }} />`
Your Remix loader would load page 2 from the url search param and your component would concat that onto `location.state.data` (the previous entries from the initial location). This renders the old data and the new data together.
Location state, unlike typical "global state", automatically persists across both refreshes and back/forward button clicks, but dies with the session, so scroll restoration will work as expected even for a refresh! Built in browser APIs tend to be a bit more resilient than storing stuff in application memory, they also keep your bundle smaller.
I don't know where the demo is, but I helped somebody at some point implement this without needing to ship a global state container for server-supplied data. Just made a note to make an example and put it our repo :)
If we're talking "load more" a much simpler way to do it is to consider how you'd do it old school with no JS. Just return all pages according to the search param, so "?page=3" would return all three pages. More kB over the network, but far easier to implement. There's even a product reason to do it this way: when you load more you automatically update the comment counts/points of each entry, so maybe it's worth it.
> I like to use "location state" which is our API into the browser's built in `history.state` ... Location state, unlike typical "global state", automatically persists across both refreshes and back/forward button clicks, but dies with the session, so scroll restoration will work as expected even for a refresh! Built in browser APIs tend to be a bit more resilient than storing stuff in application memory, they also keep your bundle smaller.
This sounds great! I never thought of using history state to store arbitrary data. Thanks for the explanation!
I was coming to say something like this, also if Remix ever supports RSC it will most likely (IMO) be under noticed, like you just name a route `.server.tsx` and it will be a RSC and that's it, I don't think Remix will need a breaking change for this and RSC seems more like an implementation detail Remix has rather than something super big for the framework.
Now uses Docker so you just need to also use Docker to run your container, there is nothing special to do to run it in locally or offline since we don't require you an specific runtime or API. Just a normal HTTP server running inside a normal Docker container.