When to use RefAppState

RefAppState and RefSlot exist for performance and scale.

They are powerful, but they are not the default way to manage state in SimpleAppState.

Most applications should use:

  • SimpleAppState

  • StateSlot

almost everywhere.

This page explains when reference-based state is appropriate, and when it is not.


The default: value semantics

SimpleAppState uses value semantics:

  • values are deep-copied on read

  • values are replaced on write

  • state transitions are explicit

  • undo, redo, and persistence are safe

This is what makes SimpleAppState easy to reason about.

For the vast majority of app state, this is exactly what you want:

  • counters

  • selections

  • settings

  • UI state

  • domain objects

  • lists and maps

If you are not sure which to use, use SimpleAppState.


What RefAppState is for

RefAppState is for data that is:

  • very large

  • expensive to copy

  • mutated frequently

  • conceptually a single object

Typical examples:

  • 3D or 2D scene graphs

  • geometry models

  • large document trees

  • binary or image buffers

Copying these on every read or update would be too slow or too memory-intensive.

RefAppState allows these objects to live as shared references while still participating in:

  • slot-based updates

  • widget rebuilds

  • undo / redo

  • persistence


Enums and identity-based models

Another valid use case is identity-based models.

For example:

  • enum-like objects

  • flyweight instances

  • canonical singletons

  • object graphs where identity matters

In these cases, copying would break meaning.

A reference slot preserves identity while still letting SimpleAppState track changes.


Why beginners should not use RefAppState

Reference semantics are harder to reason about.

With StateSlot:

  • reading never mutates state

  • updates are always explicit

  • bugs are localized

With RefSlot:

  • reading can mutate state

  • changes can happen deep inside objects

  • it is easier to forget to notify

This is powerful, but also more dangerous.

For this reason:

> RefAppState is an advanced tool for special cases.

Most application logic should stay in SimpleAppState and StateSlot.


Mixing SimpleAppState and RefAppState

It is normal to use both in one application.

A common pattern:

  • SimpleAppState for UI and domain state

  • RefAppState for large models or engines

They are designed to work together.

Widgets can subscribe to slots from both systems, and batch updates can coordinate them.


File organization

A recommended project structure is:

  • app_state.dart contains SimpleAppState and all StateSlot definitions

  • ref_state.dart contains RefAppState and all RefSlot definitions

This makes the separation explicit:

  • most developers work in app_state.dart

  • only performance-critical code touches ref_state.dart

This is a convention, not a requirement, but it helps keep reference-based state clearly isolated.


Summary

Use SimpleAppState and StateSlot by default.

Use RefAppState and RefSlot only when:

  • copying is too expensive

  • object identity must be preserved

  • the data is inherently large or mutable

If you are in doubt:

do not use RefAppState.

It is better to start with value semantics and introduce references only when you truly need them.