useProvided
Retrieves a value of type T from the surrounding context and registers the current hook as its dependent, rebuilding the hook whenever that value changes.
ProfileState useProfileState() {
// Group useProvided calls at the top of the hook.
final auth = useProvided<AuthState>(); // <- Rebuilds this hook when AuthState changes
return ProfileState(canEdit: auth.isLoggedIn);
}
Signature
T useProvided<T>();
dynamic useProvidedUnsafe(Type type);
useProvided<T>() looks up the value registered under the type T and returns it. If no such value is available, it throws ProvidedValueNotFoundException.
useProvidedUnsafe does the same lookup for a Type known only at runtime and returns dynamic. Prefer the type-safe useProvided whenever the type is known at compile time.
dynamic readDynamic(Type type) {
// Resolves a value by a Type known only at runtime - the return type is dynamic.
return useProvidedUnsafe(type);
}
The available values depend on the context the hook runs in:
- Global states registered in a
HookProviderContainerWidget - Anything provided in the tree via
ValueProviderorHookProvider - The
BuildContext, in contexts that expose one
Use cases
- Consuming a global state from a screen or another global state hook
- Reading a value handed down by a parent widget through
ValueProvider - Resolving a service when
useInjected<T>()is itself defined asuseProvided<Injector>().get()
Because the hook rebuilds when the provided value changes, the new value can drive other hooks - for example, an effect keyed on it:
GreeterState useGreeterState() {
final auth = useProvided<AuthState>();
useEffect(() {
debugPrint('Logged in: ${auth.isLoggedIn}');
return null;
}, [auth.isLoggedIn]); // <- Re-runs only when the provided value changes
return GreeterState(greeting: auth.isLoggedIn ? 'Welcome back' : 'Hello');
}
Caveats
-
Place
useProvidedcalls together at the top of the hook. Grouping the dependencies makes the structure of the hook easier to reason about, and mirrors the ordered dependency list at the app root. -
useProvidedresolves only values fromutopia_hooks' own provider mechanism - the container and the in-tree providers. It does not readpackage:provideror otherInheritedWidget-based containers. To consume those, retrieve theBuildContextand read them through it, or re-provide the value withValueProvider. -
The lookup throws when the value is missing, which usually means the provider is registered below the consumer, or not at all. The order of registration matters: a state can only depend on states registered before it.
// DON'Tfinal cart = useProvided<CartState>(); // <- Throws if CartState isn't provided above this hookWhen the value may legitimately be absent, read it through the underlying context instead of letting the exception propagate (
useBuildContext().getOrNull<T>()).
See also
- useBuildContext -
useProvided<BuildContext>(), for interacting with Flutter - HookProviderContainerWidget - where global states are registered
- ProviderWidget -
ValueProviderandHookProvider, the in-tree providers - Global state -
useProvidedin the context of app-wide state