Flutter Hooks – An Alternative to StatefulWidget Class
Last Updated :
24 Apr, 2025
Flutter Hooks is a package that was introduced in Flutter v1.9 and provides an alternative way to manage state and other side effects in Flutter. Instead of using traditional stateful widgets, hooks allow you to use functional components to manage state and other side effects. In this article, we will explore how to use Flutter hooks to improve your Flutter development experience.
Introduction to Hooks
Hooks are functions that allow you to “hook” into Flutter’s state management and other features. These are special functions that you can hook into your state widgets, in order to remove boilerplate code and make code readable and reusable. There are several built-in hooks in the Flutter hooks package, including the `useState` hook, the `useEffect` hook, and the `useContext` hook. Each of these hooks serves a different purpose and can be used to solve different problems in your Flutter application. Hooks originally came from React.
Installing Flutter Hooks
To install the Flutter hooks package:
Add the following dependency to your pubspec.yaml file:
dependencies:
flutter_hooks: ^0.18.5+1
Open a terminal window and navigate to the root directory of your Flutter project. Run the following command to add the Flutter Hooks package as a dependency in your project:
flutter pub add flutter_hooks
Then run the following command in your terminal to download the package:
flutter pub get
Once the package has been installed, you can start using it in your Flutter widgets by importing the flutter_hooks.dart file and use the hooks provided by the package.
import 'package:flutter_hooks/flutter_hooks.dart';
Get to know more about the hooks
useState hook
The useState hook is one of the most basic and commonly used hooks in the Flutter Hooks package. It allows you to add a state to your Flutter widgets, which can be used to store and manipulate data in response to user interactions or other events. With this, you do not need to use setState. Here’s a simple example of how to use the useState hook in a Flutter widget:
Dart
import 'package:flutter/material.dart' ;
import 'package:flutter_hooks/flutter_hooks.dart' ;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Hooks Example' ,
home: Counter(),
);
}
}
class Counter extends HookWidget {
final count = useState(0);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:' ,
),
Text(
'${count.value}' ,
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => count.value++,
tooltip: 'Increment' ,
child: Icon(Icons.add),
),
);
}
}
|
In this example, the useState hook is used to create a piece of state in the Counter widget. The useState hook returns a pair of values: the current state, and a setter function that can be used to update the state. In this case, the state is a simple integer that counts the number of times a button has been tapped. The value of the state is displayed in the UI, and the setter function is called every time the button is tapped, incrementing the state by one. This demonstrates how the useState hook can be used to add a state to your widgets and respond to user interactions.
useEffect hook
The useEffect hook is one of the most commonly used hooks in the Flutter Hooks package. It allows you to run side effects in response to changes in your widget’s state. For example, you can use the useEffect hook to update the UI, fetch data from an API, or listen to changes in the device’s orientation. With this hook, you do not need to worry about initializing something in your initState(), manually disposing, or stating didUpdateWidget on any changes, this hook alone will do everything for you.
Dart
import 'package:flutter/material.dart' ;
import 'package:flutter_hooks/flutter_hooks.dart' ;
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
useEffect(
() {
return () {
};
},
[],
);
return Container();
}
}
|
Above is the way you can make use of useEffect the way you want to use it. Instead of stating separate functions for dispose(), didUpdateWidget(), and the initState(), with this, you can get a cleaner code. Here’s a simple example of how to use the useEffect hook in a Flutter widget:
Dart
import 'package:flutter/material.dart' ;
import 'package:flutter_hooks/flutter_hooks.dart' ;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Hooks Example' ,
home: Counter(),
);
}
}
class Counter extends HookWidget {
final count = useState(0);
@override
Widget build(BuildContext context) {
useEffect(() {
print( 'The count has changed to ${count.value}' );
}, [count.value]);
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:' ,
),
Text(
'${count.value}' ,
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => count.value++,
tooltip: 'Increment' ,
child: Icon(Icons.add),
),
);
}
}
|
In this example, the useEffect hook is used to run a side effect every time the ‘count’ changes. The side effect simply prints a message to the console indicating the new value of the count. Note that the useEffect hook takes two arguments: a function that contains the side effect and a list of dependencies. The dependencies determine when the side effect should be rerun. In this case, the side effect will be rerun every time the count changes.
useContext hook
The useContext hook is used to access the nearest ancestor BuildContext that contains a particular type of InheritedWidget. The InheritedWidget is a special kind of widget in Flutter that allows you to share data with its descendants in the widget tree. The useContext hook will enable you to access this shared data from within a hook widget. Here’s a simple example of how to use the useContext hook:
Dart
import 'package:flutter/material.dart' ;
import 'package:flutter_hooks/flutter_hooks.dart' ;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Hooks Example' ,
home: Counter(),
);
}
}
class Counter extends HookWidget {
@override
Widget build(BuildContext context) {
final theme = useContext(ThemeData);
return Scaffold(
body: Center(
child: Text(
'${theme.brightness}' ,
style: Theme.of(context).textTheme.headline4,
),
),
);
}
}
|
In this example, the useContext hook is used to access the ThemeData from the nearest ancestor BuildContext that contains a Theme widget. The Theme widget is an InheritedWidget that is used to share the current ThemeData with its descendants in the widget tree. The useContext hook allows us to access this shared data in the Counter widget, even though it is not a direct descendant of the Theme widget.
By using the useContext hook, we can access shared data in a simple and concise way, without having to pass the data down the widget tree through constructors or callbacks. This makes it easier to manage and share data in your Flutter app, and helps to keep your code organized and maintainable.
useAnimation hook
The useAnimation hook is a hook provided by the Flutter Hooks package that makes it easy to work with animations in Flutter. The useAnimation hook allows you to create, control, and monitor an animation within a hook widget. With this, you do need to go through the hassle of extending the state class with SingleTickerProviderStateMixin, define AnimationController, override initState to initialize the animation controller, or remember to dispose of the controller, useAnimation will do all that for you. Here’s a simple example of how to use the useAnimation hook:
Dart
import 'package:flutter/material.dart' ;
import 'package:flutter_hooks/flutter_hooks.dart' ;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Hooks Example' ,
home: FadeIn(),
);
}
}
class FadeIn extends HookWidget {
@override
Widget build(BuildContext context) {
final animation = useAnimation(CurvedAnimation(
parent: useAnimationController(duration: Duration(seconds: 2)),
curve: Curves.easeIn,
));
return Scaffold(
body: Center(
child: FadeTransition(
opacity: animation,
child: Text(
'Fade In' ,
style: Theme.of(context).textTheme.headline4,
),
),
),
);
}
}
|
In this example, the useAnimation hook is used to create a CurvedAnimation with a specified curve and parent AnimationController. The useAnimationController hook is used to create and control the animation controller. The animation controller is used to control the progression of the animation over time. The useAnimation hook returns a Animation object, which can be used in conjunction with a FadeTransition widget to control the opacity of the text. The Animation object updates its value over time based on the progression of the animation controller.
By using the useAnimation hook, you can easily create and control animations in your Flutter app, without having to manage the animation state in a separate class. This makes it easier to manage and organize your animations and helps to keep your code concise and maintainable.
Similar Reads
Flutter - Stateful Widget
A Stateful Widget has states in it. To understand a Stateful Widget, you need to have a clear understanding of widgets and state management. A state can be defined as "an imperative changing of the user interface," and a widget is "an immutable description of the part of the user interface". To lear
4 min read
Difference Between Stateless and Stateful Widget in Flutter
As we all know the flutter app consists of widgets only, these are broadly classified into two types: Stateless WidgetStateful WidgetState: Before knowing the difference between the stateless and stateful widget we should take a look at the definition of State of a widget. The State is information t
3 min read
How to use Conditional Statement on Widget in Flutter?
Handling conditions is not too much difficult in Flutter. We can easily write our conditions based on the requirements which we are acquiring from our application. Let's work on conditions in flutter Apps. In this article, we'll talk about conditions and how we handle elements or widgets by using co
2 min read
Flutter - Responsive and Adaptive Apps
Whenever we are developing an app we usually develop it for a single device but it is not meant for use only on a single device but on different devices of different sizes and in case of flutter it also provides us the facility to develop for the web at the same time. So we have to deal with a range
3 min read
What are Widgets Available in Flutter?
Flutter is a mobile app development framework that allows developers to create beautiful and responsive user interfaces with ease. This is made possible through the use of Flutter widgets, which are the building blocks of every Flutter application. In Flutter, widgets are the fundamental building bl
4 min read
Flutter - Fade a Widget In and Out
The AnimatedOpacity widget in Flutter allows you to animate the opacity (transparency) of a child widget. You can use it to smoothly fade in or out a widget. In this article, we are going to implement the AnimatedOpacity Widget in Flutter and see the basic syntax of it. A sample video is given below
4 min read
Flutter - Implement Stepper Widget Inside an AlertDialog
The Stepper widget in Flutter is a user interface element used to create a step-by-step process interface. It allows users to progress through a series of steps or stages, with each step typically representing a specific task or some information. An Alert Dialog is a useful way to grab users' attent
5 min read
Flutter - AnimatedCrossFade Widget
AnimatedCrossFade Widget creates a fade transition between two widgets when one widget is replaced by another. It is used when you need to give a fade kind of transition in between two widgets. It supports any kind of Flutter Widget like Text, Images, Icon as well as anything that is extended from t
3 min read
How to Add Space Between Widgets in Flutter?
In this article, we'll learn how to add space between widgets. There are many options available in flutter which you can use to provide space and make UI attractive. If you use Row and Column for arranging widgets, then by default limited options are available for alignment. There are many options a
4 min read
Flutter - FlutterLogo Widget
FlutterLogo widget is as simple as it sounds, it is just the flutter logo in the form of an icon. This widget also comes built-in with Flutter SDK. This widget can found its use as a placeholder for an image or icon. Below we will see its implementation with all its properties and constructor. Const
3 min read