I am working on an application where the routing between pages has been implemented by adding elements to the layout initially, and then changing their visibility based on the url. In principle, a structure like this,
from dash import Dash, html, dcc, Output, Input
app = Dash()
app.layout = html.Div([
html.Div(["Page1", dcc.Link("Go to page2", href="/page2")], id="page1"),
html.Div(["Page2", dcc.Link("Go to page1", href="/page1")], id="page2", hidden=True),
dcc.Location(id="location")
])
@app.callback(Output("page1", "hidden"),
Output("page2", "hidden"),
Input("location", "pathname"))
def navigate(pathname):
if "page2" in pathname:
return [True, False]
return [False, True]
if __name__ == '__main__':
app.run_server(port=9999)
While this approach works, it quickly grows in complexity, and the application is already at a point where people are loosing the overview. I was thinking about migrating the app to use Dash pages, as this seems like a much cleaner and more scaleable approach.
However, the initial approach has one main advantage from the user perspective: The state is kept when the user navigates between pages. Hence, selections in drop downs are remembered, tables remain populated and so on. I know that (some of) this behavior can be achieved using persistence, but that requires a lot more work/configuration. And I am not sure that it will be suitable for large amounts of data (e.g. a large aggrid).
To make matters more challenging, some component are also shared between pages. It could be e.g. a large aggrid, that is used on multiple pages, and which takes a long time (several seconds) to populate. With the pages approach, I need to populate the grid on every page change - but with the toggle visbility approach, this can be avoided (at the cost of even more complex navigation code).
In essence, I don’t see any (easy) way of keeping the user experience intact, if we migrate to Dash pages. Has anyone faced similar challenges? How did you address them?