useCombinedInitializationState
Reports whether a set of provided states are all initialized. It looks up each listed type in the hook provider context, reads its isInitialized, and returns a CombinedInitializationState that is initialized only when every one of them is.
// A bootstrap gate: render the app only once every listed state is initialized.
class AppGate extends HookWidget {
const AppGate({super.key, required this.child});
final Widget child;
Widget build(BuildContext context) {
final initialization = useCombinedInitializationState({SessionState, ConfigState});
if (!initialization.isInitialized) return const Center(child: CircularProgressIndicator());
return child;
}
}
// The states must be registered above AppGate in the provider container.
class App extends StatelessWidget {
const App({super.key});
Widget build(BuildContext context) {
return const HookProviderContainerWidget(
{
SessionState: useSessionState,
ConfigState: useConfigState,
},
child: AppGate(child: Text('Ready')),
);
}
}
Signature
CombinedInitializationState useCombinedInitializationState(Set<Type> types);
class CombinedInitializationState extends HasInitialized {
const CombinedInitializationState({required super.isInitialized});
}
types- the set of provided state types to combine. Each is resolved from the surroundingHookProviderContainerWidgetand must be aHasInitialized.- The returned
isInitializedis the logical AND of every resolved state'sisInitialized.
HasInitialized is the shared readiness contract: a class with a bool isInitialized, implemented by computed and paginated states and extended by global states that load asynchronously.
Use cases
-
An app-bootstrap gate: hold the UI on a splash or loader until session, config, feature flags, and any other startup state have all loaded, then render the app in one step.
Each combined state reports its own readiness from whatever it wraps - a computed state, a stream snapshot, anything
HasInitialized:// Two global states, each reporting its own readiness via HasInitialized.class SessionState extends HasInitialized {const SessionState({required super.isInitialized});}class ConfigState extends HasInitialized {const ConfigState({required super.isInitialized});}SessionState useSessionState() {final snapshot = useAutoComputedState(() async => 'token');return SessionState(isInitialized: snapshot.isInitialized);}ConfigState useConfigState() {final snapshot = useAutoComputedState(() async => 'config');return ConfigState(isInitialized: snapshot.isInitialized);} -
Gating a feature area that depends on several globals, where waiting on each one separately would mean a cascade of loaders.
Caveats
-
Resolution is unsafe. Each type is looked up with the provider context's unsafe getter, so a type that isn't registered above this hook - or isn't a
HasInitialized- fails at runtime, not compile time. Register every listed state in theHookProviderContainerWidgetancestor. -
It combines readiness, not values. The result tells you only whether everything is initialized; read the actual data from each state through its own provider. This hook is the gate, not the accessor.
-
It depends on the provider context, so it only works inside a hook tree under a
HookProviderContainerWidget. It is not a standalone utility for arbitraryHasInitializedobjects - for those,HasInitialized.all([...])does the same AND directly.
See also
- useComputedState - a common source of a
HasInitializedstate to combine - Global state - registering the states this hook resolves, and the
HasInitializedpattern