Skip to contents

Builds a callable hierarchical state tree from a nested list. The shape rule is simple: a bare named list (length > 0) becomes a navigable reactiveStore node (every sub-tree is itself a reactiveStore); everything else becomes a plain shiny::reactiveVal() leaf that accepts any value on write. To force a bare named list to be treated as a leaf instead of a store, wrap it in base::I().

Usage

reactiveStore(initial)

Arguments

initial

A bare named list describing the initial shape. Sub-positions classify as follows: bare named lists (length > 0) become store sub-nodes; anything else (scalars, vectors, NULL, unnamed/empty bare lists, classed lists, or any value wrapped in I()) becomes a leaf. Partially-named bare lists are an error.

Value

A callable reactiveStore node with class c("reactiveStore", "reactive", "function"). Sub-trees share the same class. Leaf positions are plain shiny::reactiveVal()s with class c("reactiveVal", "reactive", "function") — the shared "reactive" class is what auto-bind dispatches on.

Details

Every node is callable: node() reads, node(value) writes. Branch writes replace: the input must list every locked key for that branch. Both unknown keys and missing keys are an error. Types are not enforced. Per-field writes (node$key(value)) remain the dedicated single-slot path — use them when you want to update one field without naming the rest.

length() on a leaf returns 1 (the underlying reactiveVal is a callable, and neither R's closure default nor shiny override length). htmltools' dropNullsOrEmpty calls length() on every attribute value, so this is what lets value = state$leaf survive tag construction. Use length(leaf()) for the underlying length.