State
Reactive values keyed by call site.
State is the primary way components hold data that drives the UI. A
StateValue[T] is a typed container; mutations schedule a re-render of the
owning component.
Creating state
State uses runtime.Caller to key the value on file and line. This means
each call site is its own state cell, and subsequent renders return the same
cell as long as you do not move the call between two different source
locations.
Use StateKey when the call site is not stable, for example inside a loop
where each iteration should allocate a distinct state cell.
Reading and writing
Getis concurrency-safe and returns the current value.Setreplaces the value and schedules a re-render.SetSilentreplaces the value without scheduling a re-render. Widgets use this internally when their own UI already reflects the new value (keystroke sync inTextField, for example). You rarely need it in application code.Updateis a read-modify-write under the state's lock. Use it whenever the next value depends on the current one.Formatreturns a reactiveSignal[string]produced byfmt.Sprintfapplied to the current value; pass it toTextfor live formatting.Lenreturns the length of a slice-, map-, string-, array- or chan-typed state. Panics on other kinds.
Slice-typed state
When T is a slice the StateValue grows convenience methods backed by
reflection. The same operations also exist as free functions (generic and
compile-time checked).
| Operation | Method (any) | Free function (typed) |
|---|---|---|
| Append | s.Append(items...) | gova.Append(s, items...) |
| Prepend | s.Prepend(item) | gova.Prepend(s, item) |
| Remove | s.RemoveWhere(pred) | gova.RemoveWhere(s, pred) |
| Update | s.UpdateWhere(pred, mut) | gova.UpdateWhere(s, pred, mut) |
The methods use any as the element type and panic on non-slice state. The
free functions are type-safe; pick whichever reads better at the call site.
Cross-goroutine safety
StateValue[T] is safe to read and write from any goroutine. Internally all
mutations take an sync.RWMutex and the re-render is scheduled through
Fyne's UI loop.
When state is reused
As long as the same State(s, initial) call is reached on each render, the
same cell is returned and initial is ignored after the first call. Moving
the call to a different source line produces a new cell; use StateKey if
you need a stable identity that is not tied to the call site.