Skip to content

State and resource ownership ​

Decide who owns each value before connecting a component to a request Hook. A Hook can protect its own state from stale results without owning your data source or undoing server work.

Application, Hook, and service ​

Arrows below name data passed or actions requested. They are ownership interactions, not package dependencies.

mermaid
flowchart LR
  App[Application] -->|creates executor and handles errors| Hook[React Hook]
  Hook -->|runs executor with abort signal| Server[Application service]
  Server -->|result or failure| Hook
  Hook -->|loading result error| UI[Application UI]
  App -->|query input and data shaping| UI
  classDef default fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
State or resourceOwner and update pathCleanup or limit
Hook loading/result/error/statususeExecutePromise holds one state value; only the execution whose AbortController is current writes itNew execution, abort(), reset() and unmount abort the controller; executor must use it to stop real work
Hook exchangeuseFetcher derives it from result or an ExchangeError, and selects explicit or registered clientShared client state has its own lifetime
Query inputYour state; useQuery / useFetcherQuery re-execute when its content changes (undefined = not ready)The Hook does not cache responses across components; share data through your own state or service
Debounce timerDebounced Hooks own their timer; debounced queries debounce the query value (pending, flush())Timer cancel()/waiting query and active request abort() are separate
Rows, totals and view preferencesThe application and its serviceFiltering, sorting, pagination and persistence are application decisions

Hook behavior: packages/react/src/core/useExecutePromise.ts:107, packages/react/src/core/useQuery.ts:58, and packages/react/src/fetcher/useFetcher.ts:67. abort() and reset() both cancel the execution in flight; abort() keeps a settled result, reset() clears it.

Stale-result protection keeps an old response from overwriting newer UI state. It does not authorize access, revoke a command already sent, or promise that a later read reflects an earlier write; decide those with the service.

Identity changes and disposal ​

Remount the subtree that owns request state when the tenant or user changes, so no Hook result crosses identities. Scope storage keys and event buses to the same identity.

ResourceWhat disposal doesWhat its creator still owns
React event subscriptionEffect cleanup removes the subscription it made, never another subscriber's handler of the same nameShared bus lifetime
KeyStoragedestroy() removes its own event handler and closes the bus it createdPersistent data and any event bus passed in eventBus; default serial bus is local, not cross-tab synchronization
BroadcastTypedEventBusdestroy() closes the messenger it created; a messenger passed in options.messenger is only detachedA messenger passed in options.messenger: close it after the bus is destroyed

See packages/react/src/eventbus/useEventSubscription.ts:94, packages/storage/src/keyStorage.ts:119, packages/storage/src/keyStorage.ts:340, and packages/eventbus/src/broadcastTypedEventBus.ts:256. Follow React cleanup, storage and events, and SSR scope.

The saved-view confirmation rules of the 5.x Viewer and FetcherViewer are documented with that line in the saved-view guide and the FetcherViewer reference.

Released under the Apache License 2.0.