Skip to main content

useBuildContext

Retrieves the BuildContext from the surrounding context, letting a hook interact with Flutter. It is exactly useProvided<BuildContext>().

ScreenMetricsState useScreenMetricsState() {
final context = useBuildContext();
final size = MediaQuery.sizeOf(context); // <- Rebuilds when the size changes

return ScreenMetricsState(isWide: size.width > 600);
}

Signature

BuildContext useBuildContext();

Returns the BuildContext of the widget the hook belongs to. It is not available in every context - a raw HookProviderContainer has no BuildContext, so calling useBuildContext there throws.

Because it is a BuildContext, it can be used to depend on InheritedWidgets such as MediaQuery or Localizations. The hook then rebuilds whenever that widget changes.

Use cases

  • Reading an InheritedWidget (MediaQuery, Theme, Localizations) and rebuilding when it changes
  • Reaching Flutter APIs that need a BuildContext (navigation, showing dialogs) from within a hook
  • Bridging a BuildContext-based DI container, e.g. T useInjected<T>() => Provider.of<T>(useBuildContext(), listen: false)

Caveats

  • Reading an InheritedWidget inside an effect won't rebuild when it changes - the effect captures the value and isn't called again. Read it during the build and pass it to the effect's keys instead.

    final context = useBuildContext();

    // CAREFUL
    useEffect(() => print("The current locale is ${Localizations.localeOf(context)}"));

    // DO
    final locale = Localizations.localeOf(context);
    useEffect(() => print("The current locale is $locale"), [locale]);
  • useBuildContext makes hooks harder to unit-test, since a test would have to supply a real BuildContext. When that is a concern, read the context-derived value in the widget and pass it into the hook as an argument:

    // The context-derived value is an argument, so the hook is testable without a
    // BuildContext.
    GreetingState useGreetingState({required Locale locale}) {
    return GreetingState(languageCode: locale.languageCode);
    }

    class GreetingScreen extends HookWidget {
    const GreetingScreen({super.key});


    Widget build(BuildContext context) {
    // The widget reads the InheritedWidget; the hook stays context-free.
    final state = useGreetingState(locale: Localizations.localeOf(context));

    return Text(state.languageCode);
    }
    }

    The hook now depends on a plain Locale rather than on Flutter, so it can be tested with a SimpleHookContext directly.

See also

  • useProvided - the general lookup useBuildContext is built on
  • Testing - unit-testing hooks without a BuildContext
  • Common hooks - useBuildContext alongside the wider hook set