:tocdepth: 2 Reactivity and effects ====================== Modern terms definition: .. glossary:: reactive In web frameworks, reactivity is the system that automatically updates the webpage (the UI) whenever the underlying data (the state) changes. imperative The opposite model to reactivity is the imperative model (often referred to as manual DOM manipulation in web development). effects In reactive web frameworks, effects (often called useEffect in React or watchEffect in Vue) are functions that run automatically when the data they depend on changes. They are used to sync your reactive data with systems outside the framework. Fortunately, `pantra` supports **both** models: reactive and imperative. Second one by default. .. note:: Despite imperative model is older at takes more code to manage, it makes logic much more explicitly obvious and code running faster, avoiding implicit unwanted effects. .. highlight:: pantra Example of imperative logic::
Nothing
def action(node): refs['message'].set_text("Hello there!") Let's imaging we want to keep message in local context::
{{message}}
message: str = "Nothing" def action(node): ctx['message'] = "Hello there!" refs['message'].update() And this code could be simplified: .. code-block:: :emphasize-lines: 1
!{{message}}
message: str = "Nothing" def action(node): ctx['message'] = "Hello there!" Noticed exclamation mark (`!`) here? It informs engine to watch for `message` variable changes and then update related node (`
` element). It works the same for attributes expressions .. code-block:: :emphasize-lines: 8

from pantra.ctx import * x: int = 0 def action(node): ctx['x'] = WebUnits(100) And for :ref:`conditional ` nodes: .. code-block:: :emphasize-lines: 1 !{{#if mode == "entry"}} {{#else}}
Hello, {{user_name}}!
{{/if}} mode: str = "entry" user_name: str = "" def action(node): ctx["mode"] = "passed" .. seealso:: Read more about :ref:`reactive macros `, :ref:`reactive attribute ` and :ref:`reactive tag `. .. note:: Reactive variable names are extracted from the expression using :mod:`ast` parser. It means there is no function call tracing for deeper variables changes. As example::
!{{get_message()}}
message: str = "Hello" def get_message(): return message # <- variable "message" will no be tracked for changes This was done consciously, to avoid possible mistakes from implicit variable changes tracking and further effects. Better practise is to make reactions explicitly: .. code-block:: :emphasize-lines: 2
{{get_message()}}
message: str = "Hello" def get_message(): return message Reed more about :ref:`node events `. Reactive dictionary ------------------- .. autoclass:: pantra.components.reactdict::ReactDict :members: