ProviderWidget
Provides values to a subtree so descendants can read them with useProvided. ValueProvider provides a single already-computed value; HookProvider provides the result of a hook; ProviderWidget is the low-level InheritedModel both build on.
class App extends StatelessWidget {
final RouterState routerState;
const App({super.key, required this.routerState});
Widget build(BuildContext context) {
// Provides an already-computed value to the subtree below.
return ValueProvider(
routerState, // <- Resolved by useProvided<RouterState>() in any descendant
child: const HomeScreen(),
);
}
}
Any descendant resolves it the usual way:
class HomeScreen extends HookWidget {
const HomeScreen({super.key});
Widget build(BuildContext context) {
final router = useProvided<RouterState>(); // <- Reads the provided value
return Text(router.initialRoute);
}
}
Use cases
- Reach for
ValueProviderwhen the value is already in hand - a constant, configuration, or an object a parent computed - and no hook needs to run to produce it. - Reach for
HookProviderwhen the value comes from a hook, so it re-provides as the hook rebuilds, scoped to one part of the tree rather than registered globally. - Reach for
ProviderWidgetonly to provide several values at once under custom keys; in app code prefer the two wrappers above.
ValueProvider
Provides a single value of type T to the subtree, keyed by T.
const ValueProvider<T>(T value, {required Widget child, Key? key});
Use it for values that don't need a hook: constants, configuration, or an already-computed object handed down from a parent. For reactive app-wide state, register a hook in a HookProviderContainerWidget instead.
HookProvider
Runs use as a hook and provides its result to the subtree, re-providing a fresh value whenever it rebuilds.
const HookProvider<T>(T Function() use, {required Widget child, Key? key});
class ShopSection extends StatelessWidget {
const ShopSection({super.key});
Widget build(BuildContext context) {
// Runs useCartState as a hook and provides its result to the subtree.
return const HookProvider(
useCartState, // <- A hook; re-provides a fresh value whenever it rebuilds
child: HomeScreen(),
);
}
}
HookProvider is a HookWidget, so use runs in a real hook context and may call other hooks. It scopes a piece of hook-driven state to one part of the tree, rather than registering it globally at the root.
ProviderWidget
The InheritedModel<Object> that backs both providers above. It holds a Map<Object, Object?> and notifies only the dependents whose key changed.
const ProviderWidget(Map<Object, Object?> values, {required Widget child, Key? key});
Reach for ValueProvider and HookProvider in app code; use ProviderWidget directly only when providing several values at once under custom keys.
Caveats
-
(All three) These widgets feed
useProvidedand theBuildContextprovider lookup - they do not interoperate withpackage:provider. A value provided here is not visible toProvider.of, and vice versa. -
(
ValueProvider) It keys the value by its static typeT. Providing a subtype under a supertype variable provides it under the variable's type, which may not be what a consumer requests.// CAREFULfinal Object config = AppConfig();ValueProvider(config, child: child); // <- Provided as Object, not AppConfig -
(
HookProvider) A consumer rebuilds only when the value it depends on changes, and that is driven by the hook: the provided value updates whenever the hook rebuilds and produces a value not equal (via==) to the previous one.
See also
- useProvided - reads the values these widgets provide
- HookProviderContainerWidget - root-level registration for app-wide states
- Global state - choosing between in-tree providers and global states