useBloc
The useBloc hook connects a React component to a state container with optimized re-renders.
const [state, bloc] = useBloc(CounterCubit);Signature
function useBloc<T extends StateContainerConstructor>(
BlocClass: T,
options?: UseBlocOptions<T>,
): [state: ExtractState<T>, bloc: InstanceType<T>, ref: ComponentRef]Return values
| Index | Name | Description |
|---|---|---|
| 0 | state | Current state snapshot. In auto-tracking mode, this is a Proxy that records property access. |
| 1 | bloc | The Cubit instance. Call methods on it (bloc.increment()). Also proxied for getter tracking. |
| 2 | ref | Internal component ref. Rarely needed — used internally for isolated instance key generation. |
Typically you destructure just the first two:
const [state, counter] = useBloc(CounterCubit);Options
autoTrack
Type: boolean — Default: true
Controls whether auto-tracking is enabled. Set to false to disable proxy-based tracking — the component re-renders on every state change.
// action-only component — doesn't read state
const [, counter] = useBloc(CounterCubit, { autoTrack: false });dependencies
Type: (state: S, bloc: T) => unknown[]
Provide an explicit dependency array. The component re-renders only when the shallow-compared values change. Setting this disables auto-tracking.
const [state] = useBloc(UserCubit, {
dependencies: (state) => [state.name, state.email],
});The function receives both state and the bloc instance, so you can depend on getters:
const [state, cart] = useBloc(CartCubit, {
dependencies: (state, bloc) => [bloc.total, state.items.length],
});instanceId
Type: string | number
Use a named instance instead of the default shared one. Components with the same instanceId share the same instance.
const [state] = useBloc(EditorCubit, { instanceId: 'doc-42' });onMount
Type: (bloc: T) => void
Called once when the component mounts with the bloc instance.
const [state] = useBloc(DataCubit, {
onMount: (bloc) => bloc.fetchData(),
});onUnmount
Type: (bloc: T) => void
Called when the component unmounts.
const [state] = useBloc(StreamCubit, {
onUnmount: (bloc) => bloc.disconnect(),
});Lifecycle
- Mount:
acquire(BlocClass)creates or retrieves the instance, incrementing the ref count - Render:
useSyncExternalStoresubscribes to state changes using the selected tracking mode - Re-render: Only triggered when tracked state properties or dependency values change
- Unmount:
release(BlocClass)decrements the ref count. At zero, the instance is disposed (unlesskeepAlive)
For isolated instances, the instance is also explicitly disposed on unmount regardless of ref count.
Concurrent mode
useBloc is built on React's useSyncExternalStore, making it safe for concurrent features like Suspense and transitions. State reads are consistent within a single render.
See also: Dependency Tracking, Shared vs Isolated, API Reference