Overview
Scopes share reactive state from a parent component to any descendant — at any depth — without prop drilling. The parent calls scope(ScopeClass) to instantiate and register a class; descendants call getParentScope(ScopeClass) to retrieve the nearest ancestor instance. Internally, retrieval bubbles a CustomEvent up the DOM tree.
Define atoms and mutation methods on the scope class. Methods are automatically bound so they can be passed as event handlers without losing this. An optional setup(propsFn) on the class receives the host component’s props function and can register lifecycle hooks (onMount, onCleanup, etc.).
App-wide utilities (router atoms, fetch client, storage bags, theme/title) live on the built-in MatesUtils store. Read them with utils (or useUtils()) — do not import those atoms as globals.
vs React Context
|
Aspect
|
Mates scope
|
Notes
|
|---|---|---|
| Provide |
scope(Class)
| Instantiates the class on the host; available to all descendants. |
| Consume |
getParentScope(Class)
| Nearest ancestor match; throws if missing — no default value API. |
| Shape | Class instance | Atoms + methods on the instance; direct method calls instead of dispatch/reducers. |
Sharing state across child components
Both Display and Controls call getParentScope(CounterScope) — they both receive the same instance created by App's scope(CounterScope). Changes in Controls instantly reflect in Display, with no props passed between them.
Nested scopes shadow the parent
A child that calls scope(ThemeScope) creates a new instance. Descendants under that child see the nested instance; siblings under App still see the parent.