Py.Cafe

maartenbreddels/

solara-reative-and-mutable

Demo: Handling Mutable Data with Reactive Variables Using Solara Library

DocsPricing
  • app.py
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# how to work with mutable data and reactive vars
import solara
import pandas
import dataclasses

store = {
    'books':'3',
    'shelves':'2',
    'racks':'1'
} # inventory


@dataclasses.dataclass
class VersionedMutableData:
    data: dict
    version: int

# wrap mutable state in a versioned object
rstore = solara.reactive(VersionedMutableData(data=store, version=0))

# convenience for setting a new store value
def set_store(store: dict):
    new_version = rstore.peek().version + 1
    rstore.value = VersionedMutableData(data=store, version=new_version)

@solara.component
def MarkdownEditor(field: str):
    store = rstore.value.data
    value = store[field]
    def store_updater(newval):
        store[field] = newval  # we mutate, which is generally not recommended
        set_store(store)  # but this one puts a new object (with a version) around it
        print('updated', store)  # debug
    solara.InputText('value '+field, value=value, on_value=store_updater)
    solara.Markdown(value)

@solara.component
def OtherDisplay1(store: dict):
    solara.Text(f"I do not update when store is mutated: {store}")


@solara.component
def OtherDisplay2(store: VersionedMutableData):
    solara.Text(f"I do  update when store is mutated: {store.data}")


@solara.component
def Page():
    store = rstore.value.data
    for fld in store.keys():
        MarkdownEditor(fld)
    print('showing as frame', store)
    df = pandas.DataFrame([[k,v] for k,v in store.items()], columns=['item','value'])
    solara.DataFrame(df)
    # possible danger is passing the mutated object as argument to component who
    # also do not see a change
    OtherDisplay1(rstore.value.data)
    # passing the verioned object will work
    OtherDisplay2(rstore.value)