Hooks are powerful functions that make filter applications in state management, dealing with side effects and smooth the code organization. Influenced by rect Hooks, they provide more comprehensive and modular approach than traditional StatefulWidget And setState Sampling
By the end of this guide, you will understand the basic hooks of the flurry, how to use them effectively, how to make your custom hooks, and how to use the best methods of using them in real -world plans.
The table of content
Provisions
Before diving into a fluttering hooks, make sure you have as follows:
SDK: Installed and configured (Submitted 3.X or more). Confirm:
flutter --versionDart SD’s: It comes with a flurry, make sure it is the latest.
ideIntelligence with visual studio codes, Android studio, or expansion.
Knowledge of the basic flutter: Familiar with the widget,
StatelessWidgetFor, for, for,.StatefulWidgetAnd the basics of state management.Package dependent:
flutter_hooksThe package has been installed by adding the followingpubspec.yaml:dependencies: flutter_hooks: ^0.21.3+1Then run away:
flutter pub get
Why hooks?
Some of the benefits of use of fluttering hooks are:
Improvement of reading and maintaining
The hooks reduce the boiler plate by directly embedded in the state and side effects of the side effects directly embedded in the construction of the widget. This makes the code clean and easy to understand.Reusable
Hooks can be summarized in customs hooks. For example, you can remove complex logic (such as bringing data) into the prevailing function again.Management of granted state
Instead of managing a singleStateObjection to the entire widget, the hooks allow you to manage small, independent pieces of the state. This is especially useful for complex UIS.Easy side effects
Like hooks likeuseEffectProvide a beautiful way to handle life cycle related tasks such as data recovery, audiences, or subscriptions.
Hucks with normal flutter
Let’s go through the explanation line through the line, the most common hooks.
How to use useState Hook in
The easiest and most used hook. This allows you to declare and manage the state within one HookWidget.
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class CounterButton extends HookWidget {
@override
Widget build(BuildContext context) {
final counter = useState<int>(0);
return ElevatedButton(
onPressed: () => counter.value++,
child: Text('Count: ${counter.value}'),
);
}
}
Clarification
useStateBegins the state with a price of state(0) 0.counter.valueReads the state.Refusal
counter.valueStimulates exactly the same kind of reconstructionsetState.
How to use useAnimationController Hook in
The controller’s life cycle handles dynamic images when handling automatically.
class AnimatedBox extends HookWidget {
@override
Widget build(BuildContext context) {
final controller = useAnimationController(
duration: const Duration(seconds: 1),
);
return FadeTransition(
opacity: controller,
child: Container(width: 100, height: 100, color: Colors.blue),
);
}
}
Clarification
Hook creates a
AnimationControllerIt lasts for 1 second.When the widget is removed, the controller is automatically dealt with.
You can mobilize dynamic images
controller.forward()Orcontroller.reverse().
How to use useEffect Hook in
Handle the side effects such as bringing data or setting up listeners.
class DataWidget extends HookWidget {
@override
Widget build(BuildContext context) {
useEffect(() {
fetchData();
return () => cancelSubscription();
}, ());
return Text('Data is loading...');
}
}
Clarification
When the widget is ready, the callback runs.
The cleaning function runs when the widget is disposed of or depends.
List of empty dependent
()This means that it only runs once.
How to use useMemoized Hook in
Until the dependence changes, it reuse expensive computations and results.
final calculatedValue = useMemoized(() => calculateExpensiveValue(), ());
Clarification
calculateExpensiveValue()He walks once and catchs the result.With the dependence provided, the function only happens when they change.
How to use useRef Hook in
Construction has a variable reference.
final textController = useRef(TextEditingController());
TextFormField(
controller: textController.value,
decoration: InputDecoration(labelText: 'Username'),
);
Clarification
useRefStores something without reconstruction.Useful for controllers, focus nodes, or variable values ​​that should not be reset.
How to use useCallback Hook in
Remembers callback to prevent unnecessary widget reconstruction.
final onPressed = useCallback(() => print('Pressed'), ());
Clarification
Without
useCallbackFunctions can be re -erected on every reconstruction.Remember Callbacks improve performance when passing as widgets
ListView.
How to use useContext Hook in
Provides direct access BuildContext Values ​​such as topics or providers.
final theme = useContext();
How to use useTextEditingController Hook in
A short hand to make text controllers.
final usernameController = useTextEditingController();
TextFormField(
controller: usernameController,
decoration: InputDecoration(labelText: 'Username'),
);
Explanation:
1. What is useTextEditingController()?
final usernameController = useTextEditingController();
Usually in the blowing, if you want to manage the text input, you create a
TextEditingController.With a common
StatefulWidgetYou’ll do something:
late TextEditingController usernameController;
@override
void initState() {
super.initState();
usernameController = TextEditingController();
}
@override
void dispose() {
usernameController.dispose();
super.dispose();
}
But with Hucks flutterYou can change all these boiler plates:
final usernameController = useTextEditingController();This hook automatically:
Creates Controller
Keeps it alive As long as the widget is present.
Demolish Of this, when the widget is destroyed.
So you no longer need to manually manage life.
2. Using a controller in one TextFormField
TextFormField(
controller: usernameController,
decoration: InputDecoration(labelText: 'Username'),
);
These
TextFormFieldIs connected tousernameController.Whatever user type in the input field will be stored
usernameController.text.You can read it or edit it at any time:
print(usernameController.text); usernameController.text = "Anthony";
3. How does it work together
useTextEditingController()Provides ready to useTextEditingControllerWithout the problem of init/disposal.TextFormFieldUses this controller to handle the user’s input.It is Hooksway To handle text fields.
Abstract
useTextEditingController()→ Hook to make and dispose of hookTextEditingControllerAutomatically.TextFormField(controller: ...)The field uses this controller to handle and access the text in the field.Cleaner and more secure than manually handling/disposal
StatefulWidget.
How to make a custom hook in the flurry
You can re -use the logic in the usable hooks.
Future<String> useFetchData() {
final data = useState<String>('Loading...');
useEffect(() {
Future.microtask(() async {
data.value = await fetchDataFromApi();
});
return null;
}, ());
return data.value;
}
Explanation:
1. Signature of the function
Future<String> useFetchData()
At first glance, it seems that this function should be returned Future.
But in fact, the function does not return FutureIt looted data.valueWhich is a String.
So the correct signature should really be:
String useFetchData()
Because what you are returning is the current state of data, not Future.
2. Setup of State
final data = useState<String>('Loading...');
This creates a state variable
dataWith the initial value of"Loading...".data.valueThe original string is value.Refusal
data.valueWill regenerate the widget.
3. The impact hook
useEffect(() {
Future.microtask(() async {
data.value = await fetchDataFromApi();
});
return null;
}, ());
useEffectOnce runs (because the list of dependent()Empty).Inside her, a
Future.microtaskASYNC Work System for Bringing Data.Once the API call will end,
data.valueHas been updated with the answerfetchDataFromApi().Refusal
data.valueThe rebuilding stimulates, so UI will now show new data instead of"Loading...".
4. Returning value
return data.value;
It looted the current state value (
'Loading...'Initially, later replacing the recovered data).On the first construction, you will find
"Loading...".After the API call is over, rebuild and now
useFetchData()The recovery will return.
5. How does it work practically
Imagine this widget code:
class MyWidget extends HookWidget {
@override
Widget build(BuildContext context) {
final result = useFetchData();
return Text(result);
}
}
Step 1 → Ui Shoes "Loading...".
Step 2 → API is called in the background.
Step 3 → When API’s reaction comes, data.value Refreshments.
Step 4 → Reconstruct the widget and now Text(result) Shows recovered data.
Abstract
useStateKeeps data (Loading...Result was concluded).useEffectASYNC runs once to mobilize.When the recovery ends, this state shows a new value to the UI’s reconstruction of the widget.
The function should be returned A
StringNotFuture.
Advanced hooks
useListenable: Works withValueNotifierOrChangeNotifier.useDebounced: Useful useful of search fields, debrons the input.usePreviousState(From community libraries): monitors the previous price.
Demonstration: Counter example with hooks
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class Counter extends HookWidget {
@override
Widget build(BuildContext context) {
final count = useState<int>(0);
useEffect(() {
print('Count updated: ${count.value}');
return null;
}, (count.value));
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: (
Text('You clicked ${count.value} times', style: TextStyle(fontSize: 24)),
ElevatedButton(
onPressed: () => count.value++,
child: Text('Increment'),
),
),
);
}
}
Explanation:
This code is using flutter_hooks Package to manage the state and life cycle in a functional manner rather than normal StatefulWidget + setState. Let’s break it step by step:
1. Class appreciation
class Counter extends HookWidget {
@override
Widget build(BuildContext context) {
...
}
}
CounterGrowthHookWidgetInstead ofStatelessWidgetOrStatefulWidget.HookWidgetAllows you to use hooks (likeuseStateFor, for, for,.useEffect) Straight insidebuildHow to manage the state and side effects.
2. State with useState
final count = useState<int>(0);
useStateThere is a hook that creates a piece of state.Here, it starts
countWith0.countNot just oneintBut aValueNotifier(Mean you can readcount.valueAnd update it by assigningcount.value,
So early:count.value = 0.
3. Effect with useEffect
useEffect(() {
print('Count updated: ${count.value}');
return null;
}, (count.value));
useEffectWhen dependent changes, side effects are used to perform.In this case, it goes on whenever
count.valueChangesIt prints the latest price on the console every time the counter change.
Second
(count.value)There is a list of dependence (such as reacting hooks). Unlesscount.valueChanges, this effect runs again.
4. ui
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: (
Text('You clicked ${count.value} times', style: TextStyle(fontSize: 24)),
ElevatedButton(
onPressed: () => count.value++,
child: Text('Increment'),
),
),
);
Because count A ValueNotifierRefreshing count.value Automatically mobilize the reorganization of the widow.
5. How does it work practically
The app shows: “You clicked 0 times” and a button “Enrollment”.
When you tap the button:
count.valueIncreased by 1.Reconstruction of the widow shows the latest count.
useEffectRuns, printingCount updated: XTo the console
Summary:
This code is a counter app that is made using the flutter hooks.
useStateThe counter manages the state.useEffectHears for changes in the counter and runs by side effect (printing on the console).The UI shows the count and a button to increase it.
Best practice
Use dependent lists correctly With
useEffectAnduseMemoized.Don’t get more engineers: Sometimes
StatefulWidgetEasy.Well testsEspecially when there are side effects.
Removal of reusable logic Customs hooks to keep the widget focused.
What are the state widgets?
A Statfelt widget is a widget that can change over time as it has a state of change.
How do they work
When something changes in the state, you call
setState().It asks to rebuild the widget tree with the latest condition.
Example:
class Counter extends StatefulWidget {
@override
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: (
Text('You clicked $count times'),
ElevatedButton(
onPressed: () => setState(() => count++),
child: Text('Increment'),
),
),
);
}
}
Key points
Easy UI is good for the state (such as counters, toggles, form fields).
The fluttering manages the width of the widget’s life cycle.
You handle the start
initStateAnd in cleaningdispose.
In short:
There are state widgets Classic method Managing the state in the clash. They are straightforward to the early people and are the best of the Great for easy use. For more complicated or re -usable state logic, hooks (or state management library such as block, rapid) can be clean and more expanded.
Summary:
Hooks: Cleaner, modular, re -usable, great to deal with the latest state.
State Vegit: Early easy and simple for the state.