Skip to main content

useIsMounted

Returns a function that reports whether the hook's context is still mounted. Call it inside async callbacks before touching state, so updates that resolve after teardown are skipped.

class ProfileLoader extends HookWidget {
final Future<String> Function() load;

const ProfileLoader({super.key, required this.load});


Widget build(BuildContext context) {
final name = useState<String?>(null);
final isMounted = useIsMounted();

useEffect(() {
Future<void> run() async {
final result = await load();
if (isMounted()) name.value = result; // <- Skip the update if torn down
}

unawaited(run());
return null;
}); // <- No keys: runs once on mount

return Text(name.value ?? 'Loading...');
}
}

Signature

IsMounted useIsMounted();

typedef IsMounted = bool Function();

Returns an IsMounted callback. Calling it returns true while the context is alive and false once it has been destroyed. The same callback instance stays valid for the lifetime of the hook, so it is safe to capture in a closure.

Use cases

  • Guarding a useState update that happens after an await, when the widget may already be gone
  • Bailing out early from an async loop or a stream handler once the context is torn down

Caveats

  • useIsMounted only tells you the current state; it does not stop pending work. You still have to check it yourself at the right moment - typically right after each await, before writing state.

    final state = useState(0);
    final isMounted = useIsMounted();

    useEffect(() async {
    await Future.delayed(const Duration(seconds: 1));
    if (isMounted()) state.value++; // <- Without this guard, setting value after dispose throws
    return null;
    });
  • When the value you guard lives in a useState, prefer its built-in setIfMounted(value) extension - it performs the mounted check and the assignment in one step:

    // Equivalent, more concise:
    if (!state.setIfMounted(next)) return;

See also

  • useState - setIfMounted packages the mounted-check-then-set in one call
  • useEffect - where the async lifetime problem most often appears