mobx-router icon indicating copy to clipboard operation
mobx-router copied to clipboard

Scroll Position Restoration

Open eugenkiss opened this issue 7 years ago • 2 comments

Restoring the scroll position in SPAs seems to be a difficult problem in general. Mainly, because data is loaded asynchronously again when you go back. See, e.g., https://brigade.engineering/maintaining-scroll-positions-in-all-browsers-a280d49bffca.

Do you have ideas how you would adjust mobx-router so that it can support scroll position restoration? Or some other transient UI-specific state (e.g., hidden/opened UI elements) that you don't want to encode as query parameters?

eugenkiss avatar Jan 22 '17 09:01 eugenkiss

This is an interesting issue @eugenkiss. I will think about a way of implementing it.

kitze avatar Mar 15 '17 21:03 kitze

FYI, I've tried a specific approach in a branch of my project: https://github.com/eugenkiss/static-mobx-routing/tree/rewrite

The idea is roughly as follows:

First, the assumptions: Routes are part of a list (the history) that is (de)serialized and there is a pointer/index that points to the current route in the history. This pointer moves according to the user's history manipulation (e.g. pressing the back button decreases the by 1).

Components can register themselves to save arbitrary state in the current route before the route is left. See https://github.com/eugenkiss/static-mobx-routing/blob/b4d844e13df06cd5cac6212e7a9b527ab311e3fa/src/app/history.ts#L8 (uiStates) and https://github.com/eugenkiss/static-mobx-routing/blob/b4d844e13df06cd5cac6212e7a9b527ab311e3fa/src/app/comps/post.tsx#L51 (saveUiListener and autorunRestoreUiState). Note that simply deserializing in componentDidMount without autorun does not suffice as the component can stay mounted while its data completely changes (e.g. go from one post to another).

So, the main idea is that the component itself is responsible for saving and restoring UI-specific state that it cares about (scroll position, hidden/opened UI elements, selections, etc.). This is similar to Android's approach and it intuitively makes sense to me. Plus, there is no need for rough heuristics as described in the above blog post.

Caution: My current implementation is WIP and does not work for at least one use case yet.

If you have any thoughts/ideas @kitze, please let me know.

eugenkiss avatar Mar 16 '17 08:03 eugenkiss