Flutter, framework phát triển ứng dụng đa nền tảng của Google, đã trở thành một lựa chọn hàng đầu nhờ hiệu suất cao, giao diện người dùng linh hoạt và khả năng tái sử dụng mã nguồn. Một trong những khía cạnh quan trọng khi làm việc với Flutter là quản lý state (trạng thái), yếu tố quyết định cách dữ liệu thay đổi và hiển thị trong ứng dụng. Bài viết này sẽ cung cấp cái nhìn tổng quan về quản lý state trong Flutter, từ các phương pháp cơ bản đến các giải pháp nâng cao, cùng với hướng dẫn chi tiết để bạn áp dụng hiệu quả.
State Là Gì Trong Flutter?
State (trạng thái) trong Flutter là dữ liệu thay đổi trong suốt vòng đời của ứng dụng, ảnh hưởng đến giao diện người dùng hoặc logic nghiệp vụ. Việc quản lý state tốt giúp ứng dụng hoạt động mượt mà, dễ bảo trì và mở rộng.
Phân Loại State Trong Flutter
Flutter chia state thành hai loại chính:
- Ephemeral State (Trạng thái tạm thời): Trạng thái cục bộ, chỉ tồn tại trong một widget cụ thể, như trạng thái của một nút bấm hoặc ô nhập liệu.
- App State (Trạng thái ứng dụng): Trạng thái toàn cục, ảnh hưởng đến nhiều phần của ứng dụng, chẳng hạn như thông tin người dùng hoặc dữ liệu từ API.
Tại Sao Quản Lý State Quan Trọng?
Khi ứng dụng đơn giản, bạn có thể dễ dàng quản lý state bằng cách gọi setState(). Tuy nhiên, khi ứng dụng phức tạp hơn với nhiều màn hình và tính năng, việc quản lý state không hiệu quả có thể dẫn đến mã nguồn rối rắm, khó debug và hiệu suất kém. Quản lý state tốt giúp:
- Tách biệt giao diện và logic.
- Đồng bộ dữ liệu giữa các widget.
- Tăng khả năng tái sử dụng mã.

Các Phương Pháp Quản Lý State Trong Flutter
Flutter cung cấp nhiều cách tiếp cận để quản lý state, từ cơ bản đến nâng cao, phù hợp với các loại dự án khác nhau. Dưới đây là những phương pháp phổ biến nhất.
Sử Dụng setState()
setState() là cách đơn giản nhất để quản lý state trong Flutter, tích hợp sẵn trong framework.
Cách Hoạt Động
- Gọi
setState()để thông báo Flutter rằng trạng thái đã thay đổi, từ đó yêu cầu widget rebuild. - Thích hợp cho các thay đổi nhỏ, cục bộ.
Ví dụ:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Counter: $_counter')),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
child: Icon(Icons.add),
),
);
}
}
Ưu Điểm Và Nhược Điểm
- Ưu điểm: Dễ sử dụng, không cần thư viện ngoài.
- Nhược điểm: Không phù hợp cho ứng dụng lớn, dễ gây rebuild không cần thiết.
InheritedWidget: Chia Sẻ State Cơ Bản
InheritedWidget là một giải pháp tích hợp sẵn, cho phép chia sẻ state giữa các widget trong cây widget.
Cách Sử Dụng
- Tạo một
InheritedWidgetđể lưu trữ state. - Các widget con truy cập state thông qua
context.dependOnInheritedWidgetOfExactType.
Ví dụ:
class MyInheritedWidget extends InheritedWidget {
final int counter;
MyInheritedWidget({required this.counter, required Widget child}) : super(child: child);
@override
bool updateShouldNotify(MyInheritedWidget oldWidget) => counter != oldWidget.counter;
static MyInheritedWidget? of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MyInheritedWidget(
counter: 5,
child: Builder(
builder: (context) => Text('Counter: ${MyInheritedWidget.of(context)!.counter}'),
),
);
}
}
Ưu Điểm Và Nhược Điểm
- Ưu điểm: Không cần thư viện, nhẹ nhàng.
- Nhược điểm: Khó mở rộng, không hỗ trợ logic phức tạp.
Provider: Giải Pháp Phổ Biến
Provider là thư viện quản lý state được cộng đồng ưa chuộng nhờ tính đơn giản và hiệu quả.
Cài Đặt Provider
- Thêm vào
pubspec.yaml:
dependencies:
provider: ^6.0.0
- Chạy
flutter pub get.
Cách Sử Dụng Provider
- Tạo một lớp quản lý state (thường kế thừa
ChangeNotifier). - Bọc ứng dụng bằng
ProviderhoặcChangeNotifierProvider. - Sử dụng
ConsumerhoặcProvider.ofđể truy cập state.
Ví dụ:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class CounterModel extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (_) => CounterModel(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Provider Demo')),
body: Center(
child: Consumer<CounterModel>(
builder: (context, counter, child) => Text('Count: ${counter.count}'),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Provider.of<CounterModel>(context, listen: false).increment(),
child: Icon(Icons.add),
),
),
);
}
}
Ưu Điểm Và Nhược Điểm
- Ưu điểm: Dễ học, tích hợp tốt với Flutter.
- Nhược điểm: Hạn chế với các ứng dụng cực kỳ phức tạp.
BLoC: Quản Lý State Theo Luồng
BLoC (Business Logic Component) là mẫu thiết kế sử dụng Streams để quản lý state dựa trên sự kiện.
Cài Đặt BLoC
- Thêm dependency:
dependencies:
flutter_bloc: ^8.0.0
- Chạy
flutter pub get.
Cách Sử Dụng BLoC
- Định nghĩa Event (sự kiện) và State (trạng thái).
- Tạo Bloc để xử lý logic và phát state mới.
Ví dụ:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
class CounterState {
final int count;
CounterState(this.count);
}
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(0)) {
on<IncrementEvent>((event, emit) => emit(CounterState(state.count + 1)));
}
}
void main() {
runApp(
BlocProvider(
create: (_) => CounterBloc(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('BLoC Demo')),
body: Center(
child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) => Text('Count: ${state.count}'),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<CounterBloc>().add(IncrementEvent()),
child: Icon(Icons.add),
),
),
);
}
}
Ưu Điểm Và Nhược Điểm
- Ưu điểm: Tách biệt logic, phù hợp với ứng dụng lớn.
- Nhược điểm: Phức tạp, cần hiểu Streams.

Riverpod: Sự Tiến Hóa Hiện Đại
Riverpod là phiên bản cải tiến của Provider, linh hoạt và mạnh mẽ hơn.
Cài Đặt Riverpod
- Thêm dependency:
dependencies:
flutter_riverpod: ^2.0.0
- Chạy
flutter pub get.
Cách Sử Dụng Riverpod
- Tạo provider bằng
Provider,StateProvider, hoặcStateNotifierProvider. - Truy cập state bằng
ref.watchtrongConsumerWidget.
Ví dụ:
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final counterProvider = StateProvider<int>((ref) => 0);
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(counterProvider);
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Riverpod Demo')),
body: Center(child: Text('Count: $count')),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.read(counterProvider.notifier).state++,
child: Icon(Icons.add),
),
),
);
}
}
Ưu Điểm Và Nhược Điểm
- Ưu điểm: Linh hoạt, không cần
BuildContext, dễ kiểm thử. - Nhược điểm: Khúc học tập cao hơn Provider.
So Sánh Các Phương Pháp Quản Lý State
| Phương pháp | Độ phức tạp | Phù hợp với dự án | Hiệu suất | Dễ học |
|---|---|---|---|---|
| setState | Thấp | Nhỏ | Trung bình | Cao |
| InheritedWidget | Trung bình | Nhỏ đến vừa | Trung bình | Trung bình |
| Provider | Trung bình | Nhỏ đến vừa | Cao | Cao |
| BLoC | Cao | Vừa đến lớn | Cao | Trung bình |
| Riverpod | Trung bình | Nhỏ đến lớn | Cao | Trung bình |
Mẹo Thực Tế Khi Quản Lý State
Chọn Phương Pháp Phù Hợp
- Dự án nhỏ: Dùng
setState()hoặc Provider. - Dự án lớn: Chọn BLoC hoặc Riverpod để quản lý tốt hơn.
Tối Ưu Hiệu Suất
- Sử dụng
constcho widget tĩnh để giảm rebuild. - Với Provider/Riverpod, chia nhỏ provider để tránh rebuild toàn cục không cần thiết.
Tổ Chức Mã Nguồn
- Tách logic state vào các lớp riêng (ví dụ:
CounterBloc,CounterModel). - Sử dụng cấu trúc thư mục như
blocs/,providers/,models/để dễ quản lý.
Khắc Phục Vấn Đề Thường Gặp
Widget Không Cập Nhật
- Kiểm tra xem bạn đã gọi
notifyListeners()(Provider) hoặcemit()(BLoC) chưa. - Đảm bảo widget lắng nghe đúng provider/bloc.
Hiệu Suất Kém
- Tránh rebuild toàn bộ cây widget bằng cách sử dụng
ConsumerhoặcBlocBuildervới phạm vi nhỏ. - Dùng công cụ DevTools của Flutter để phân tích hiệu suất.
Tài Nguyên Học Tập
- Tài liệu chính thức: flutter.dev cung cấp hướng dẫn chi tiết.
- Cộng đồng: Tham gia nhóm Flutter trên Discord hoặc Stack Overflow.
- Video: Tìm các hướng dẫn trên YouTube từ kênh Flutter hoặc Reso Coder.
Kết Luận
Quản lý state trong Flutter là một kỹ năng cốt lõi mà mọi lập trình viên cần nắm vững để xây dựng ứng dụng hiệu quả. Từ setState() đơn giản đến các giải pháp mạnh mẽ như BLoC và Riverpod, Flutter cung cấp nhiều lựa chọn phù hợp với từng nhu cầu. Điều quan trọng là hiểu rõ yêu cầu dự án của bạn và chọn phương pháp phù hợp.
Hãy bắt đầu với Provider để làm quen, sau đó khám phá BLoC hoặc Riverpod khi bạn cần quản lý state phức tạp hơn. Với thực hành và sự hỗ trợ từ cộng đồng Flutter, bạn sẽ sớm trở thành chuyên gia trong lĩnh vực này. Chúc bạn thành công trong việc phát triển ứng dụng Flutter tuyệt vời!
