S
Solara•2mo ago
Lisa

Switching Tabs resets a state when lazy loading is set to True

I want to keep local state of components when switching Tabs but also I need lazy=True since I don't want inactive tabs to be rendered. Unfortunately, it seems to be impossible to have both. With lazy=True the local state of the components resets to default values, in the attached example I used solara.use_state, but the same holds true for solara.use_reactive. Is there a way to keep local state of the component when switching Tabs and having lazy loading too?
3 Replies
MaartenBreddels
MaartenBreddels•2mo ago
Hi Lisa, I think you'd want to lift state up into the parent component, and then pass it down to the resuable component:
import solara


@solara.component
def ClickButton(clicks: solara.Reactive[int]):
def my_click_hander():
clicks.value += 1

return solara.Button(label=f"Clicked: {clicks.value}", on_click=my_click_hander)


@solara.component
def Page():
clicks1 = solara.use_reactive(0)
clicks2 = solara.use_reactive(0)
with solara.lab.Tabs(lazy=True):
with solara.lab.Tab(label="Tab 1"):
ClickButton(clicks1)
with solara.lab.Tab(label="Tab 2"):
ClickButton(clicks2)

Page()
import solara


@solara.component
def ClickButton(clicks: solara.Reactive[int]):
def my_click_hander():
clicks.value += 1

return solara.Button(label=f"Clicked: {clicks.value}", on_click=my_click_hander)


@solara.component
def Page():
clicks1 = solara.use_reactive(0)
clicks2 = solara.use_reactive(0)
with solara.lab.Tabs(lazy=True):
with solara.lab.Tab(label="Tab 1"):
ClickButton(clicks1)
with solara.lab.Tab(label="Tab 2"):
ClickButton(clicks2)

Page()
Does this solve your problem? In this case i've used reactive variables, and you can also have them top level using solara.reactive
Lisa
Lisa•2mo ago
Does that mean if I have, for example, around 10 or more reactive variables across all the components in each Tab and there are 5 or more tabs, then that makes at least 50 reactive variables we have to define and pass to each tab? That would make the code complicated to work with. Is there any other way to handle this? Would it make sense to have some mechanism to keep the state within the component even when using lazy loading? Thank you for the answer! 🙂
MaartenBreddels
MaartenBreddels•2mo ago
In your example, you were using a re-usable component. But I think you are not looking to use that, but a component that has application specific parts, is that correct? If that is the case, you could do something like this:
import solara


# tab 1
clicks1 = solara.reactive(0)

@solara.component
def Page1():
def my_click_hander():
clicks1.value += 1

return solara.Button(label=f"Clicked: {clicks1.value}", on_click=my_click_hander)


# tab 2
clicks2 = solara.reactive(0)

@solara.component
def Page2():
def my_click_hander():
clicks2.value += 1

return solara.Button(label=f"Clicked: {clicks2.value}", on_click=my_click_hander)


@solara.component
def Page():
with solara.lab.Tabs(lazy=True):
with solara.lab.Tab(label="Tab 1"):
Page1()
with solara.lab.Tab(label="Tab 2"):
Page2()

Page()
import solara


# tab 1
clicks1 = solara.reactive(0)

@solara.component
def Page1():
def my_click_hander():
clicks1.value += 1

return solara.Button(label=f"Clicked: {clicks1.value}", on_click=my_click_hander)


# tab 2
clicks2 = solara.reactive(0)

@solara.component
def Page2():
def my_click_hander():
clicks2.value += 1

return solara.Button(label=f"Clicked: {clicks2.value}", on_click=my_click_hander)


@solara.component
def Page():
with solara.lab.Tabs(lazy=True):
with solara.lab.Tab(label="Tab 1"):
Page1()
with solara.lab.Tab(label="Tab 2"):
Page2()

Page()
Here the state is outside of the component, which is usually what you want for applications (no need to make multiple instances) This is very similar to the multipage examples in solara, does this match what you need or want?
Want results from more Discord servers?
Add your server
More Posts