Skip to content

prefer_use_callback

v0.4.0 Warning Fix Hook Rules

Flags uses of useMemoized where the factory function returns another function. When you are memoizing a callback, useCallback is the semantically correct hook to use. useMemoized is designed for expensive non-function values.

useCallback communicates intent more clearly than useMemoized(() => someFunction). It signals that you are memoizing a callback, not computing an expensive value. Using the right hook improves readability and aligns with the hooks naming conventions from React and flutter_hooks.

See also: flutter_hooks - useCallback

class BadWidget extends HookWidget {
const BadWidget({super.key});
@override
Widget build(BuildContext context) {
// useMemoized wrapping a closure
final onPressed = useMemoized(
() => () {
debugPrint('pressed');
},
);
// useMemoized wrapping a tear-off
final onTap = useMemoized(() => _handleTap);
return ElevatedButton(onPressed: onPressed, child: const Text('Tap'));
}
void _handleTap() => debugPrint('tapped');
}
class GoodWidget extends HookWidget {
const GoodWidget({super.key});
@override
Widget build(BuildContext context) {
// useCallback for memoizing callbacks
final onPressed = useCallback(() {
debugPrint('pressed');
}, []);
return ElevatedButton(onPressed: onPressed, child: const Text('Tap'));
}
}
// useMemoized is fine for non-function values:
final expensiveValue = useMemoized(() => List.generate(100, (i) => i));

To disable this rule:

plugins:
many_lints:
diagnostics:
prefer_use_callback: false