Last updated:
0 purchases
flutter hooks lint
flutter_hooks_lintπͺπ΄ββ οΈ #
A lint package providing guidelines for using flutter_hooks in your Flutter widget! π¦
You can keep code that follows the rules outlined in the official documentation of flutter_hooks. β
A lint rules are available to improve both performance and readability. β¨
A lint rules supporting hooks_riverpod has been prepared. π§βπ€βπ§
The currently available lint rules are as follows:
LintRule
Description
Quickfix
hooks_avoid_nesting
You should use Hooks only inside the build method of a Widget.
hooks_avoid_within_class
Hooks must not be defined within the class.
hooks_name_convention
DO always prefix your hooks with use, https://pub.dev/packages/flutter_hooks#rules.
β
hooks_extends
Using Hooks inside a Widget other than HookWidget or HookConsumerWidget will result in an error at runtime.
β
hooks_unuse_widget
If you are not using Hooks inside of a Widget, you do not need HookWidget or HookConsumerWidget.
β
hooks_memoized_consideration
Considering performance and functionality, there may be places where it is worth considering the use of useMemoized.
β
hooks_callback_consideration
There are cases where you can use useCallback, which is the syntax sugar for useMemoized.
β
Installation #
Add both flutter_hooks_lint and custom_lint to your pubspec.yaml:
dev_dependencies:
custom_lint:
flutter_hooks_lint:
copied to clipboard
Enable custom_lint's plugin in your analysis_options.yaml:
analyzer:
plugins:
- custom_lint
copied to clipboard
Enabling/disabling lints #
By default when installing flutter_hooks_lint, most of the lints will be enabled.
You may dislike one of the various lint rules offered by flutter_hooks_lint. In that event, you can explicitly disable this lint rule for your project by modifying the analysis_options.yaml
analyzer:
plugins:
- custom_lint
custom_lint:
rules:
# Explicitly disable one lint rule
- hooks_unuse_widget: false
copied to clipboard
Running flutter_hooks_lint in the terminal/CI π€ #
Custom lint rules created by flutter_hooks_lint may not show-up in dart analyze. To fix this, you can run a custom command line: custom_lint.
Since your project should already have custom_lint installed, then you should be able to run:
# Install custom_lint for project
dart pub get custom_lint
# run custom_lint's command line in a project
dart run custom_lint
copied to clipboard
Alternatively, you can globally install custom_lint:
# Install custom_lint for all projects
dart pub global activate custom_lint
# run custom_lint's command line in a project
custom_lint
copied to clipboard
All the lints #
hooks_avoid_nesting #
You should use Hooks only inside the build method of a Widget.
https://pub.dev/packages/flutter_hooks#rules
Bad:
@override
Widget build(BuildContext context) {
if (isEnable) {
final state = useState(0); // β
return Text(state.value.toString());
} else {
return SizedBox.shrink();
}
}
copied to clipboard
Good:
@override
Widget build(BuildContext context) {
final state = useState(0); // β
return isEnable ?
Text(state.value.toString()) :
SizedBox.shrink();
}
copied to clipboard
hooks_avoid_within_class #
Defining Custom Hooks within a class mixes the characteristics of class and method, leading to potentially complex code.
Bad
class TestHelper {
const TestHelper._();
static void useEffectOnce(Dispose? Function() effect) { // β
useEffect(effect, const []);
}
}
copied to clipboard
Good:
void useEffectOnce(Dispose? Function() effect) { // β
useEffect(effect, const []);
}
copied to clipboard
hooks_name_convention #
DO always prefix your hooks with use.
https://pub.dev/packages/flutter_hooks#rules.
Bad:
class WrongMethodWidget extends HookWidget {
@override
Widget build(BuildContext context) {
effectOnce(() { // β
return;
});
return Text('');
}
}
copied to clipboard
Good:
class CorrectMethodWidget extends HookWidget {
@override
Widget build(BuildContext context) {
useEffectOnce(() { // β
return;
});
return Text('');
}
}
copied to clipboard
hooks_extends #
Using Hooks inside a Widget other than HookWidget or HookConsumerWidget will result in an error at runtime.
Bad:
class RequiresHookWidget extends StatelessWidget { // β
@override
Widget build(BuildContext context) {
final state = useState(0);
return Text(state.value.toString());
}
}
class RequiresConsumerHookWidget extends ConsumerWidget { // β
@override
Widget build(BuildContext context, WidgetRef ref) {
final state = useState(0);
return Text(state.value.toString());
}
}
copied to clipboard
Good:
class RequiresHookWidget extends HookWidget { // β
@override
Widget build(BuildContext context) {
final state = useState(0);
return Text(state.value.toString());
}
}
class RequiresConsumerHookWidget extends HookConsumerWidget { // β
@override
Widget build(BuildContext context, WidgetRef ref) {
final state = useState(0);
return Text(state.value.toString());
}
}
copied to clipboard
hooks_unuse_widget #
If you are not using Hooks inside of a Widget, you do not need HookWidget or HookConsumerWidget.
Bad:
class UnuseHookWidget extends HookWidget { // β
@override
Widget build(BuildContext context) {
return SizedBox.shrink();
}
}
class UnuseHookConsumerWidget extends HookConsumerWidget { // β
@override
Widget build(BuildContext context, WidgetRef ref) {
return SizedBox.shrink();
}
}
copied to clipboard
Good:
class UnuseHookWidget extends StatelessWidget { // β
@override
Widget build(BuildContext context) {
return SizedBox.shrink();
}
}
class UnuseHookConsumerWidget extends ConsumerWidget { // β
@override
Widget build(BuildContext context, WidgetRef ref) {
return SizedBox.shrink();
}
}
copied to clipboard
hooks_memoized_consideration #
Considering functionality, there may be places where it is worth considering the use of useMemoized.
https://api.flutter.dev/flutter/widgets/GlobalKey-class.html
Bad
class ConsiderationMemoizedWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final key = GlobalKey<TooltipState>(); // β
final objectKey = GlobalObjectKey<TooltipState>("object"); // β
return Column(
children: [key, objectKey]
.map((k) => Tooltip(
key: key,
message: 'Click me!',
))
.toList());
}
}
copied to clipboard
Good
class ConsiderationMemoizedWidget extends HooksWidget {
@override
Widget build(BuildContext context) {
final key = useMemoized(() => GlobalKey<TooltipState>()); // β
final objectKey = useMemoized(() => GlobalObjectKey<TooltipState>("object")); // β
return Column(
children: [key, objectKey]
.map((k) => Tooltip(
key: key,
message: 'Click me!',
))
.toList());
}
}
copied to clipboard
hooks_callback_consideration #
There are cases where you can use useCallback, which is the syntax sugar for useMemoized.
https://pub.dev/documentation/flutter_hooks/latest/flutter_hooks/useCallback.html
Bad
class ConsiderationMemoizedWidget extends HookWidget {
@override
Widget build(BuildContext context) {
final state = useMemoized(() => () => 0); // β
return Text(state.call().toString());
}
}
copied to clipboard
Good
class ConsiderationMemoizedWidget extends HookWidget {
@override
Widget build(BuildContext context) {
final state = useCallback(() => 0); // β
return Text(state.call().toString());
}
}
copied to clipboard
Contribution π #
Thanks for your interest! Issues and PR are welcomed! π
I would be delighted if you could translate the documentation into natural English or add new lint rules!
The project setup procedures for development are as follows:
Fork it ( https://github.com/nikaera/flutter_hooks_lint/fork )
Create your fix/feature branch (git checkout -b my-new-feature)
Install Melos ( dart pub global activate melos )
Set up the project and run the test ( melos bs )
Add a test each time you modify
4. it is possible to check the operation by executing the command ( melos bs )
Commit your changes (git commit -am 'Add some feature')
Push to the branch (git push origin my-new-feature)
Create new Pull Request! π
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.