Skip to main content

One post tagged with "State"

View All Tags

Flutter: State trong StatefulWidget

· 5 min read

State là một khái niệm quan trọng trong Flutter, đặc biệt khi làm việc với StatefulWidget. Bài viết này sẽ giúp bạn hiểu rõ về cách quản lý state và các phương pháp hiệu quả.

StatefulWidget & State

1. StatefulWidget và State

1.1. Cấu trúc cơ bản

class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Counter: $_counter'),
ElevatedButton(
onPressed: _incrementCounter,
child: Text('Increment'),
),
],
);
}
}

1.2. Vòng đời của State

class _MyWidgetState extends State<MyWidget> {
@override
void initState() {
super.initState();
// Khởi tạo state
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
// Xử lý khi dependencies thay đổi
}

@override
void didUpdateWidget(MyWidget oldWidget) {
super.didUpdateWidget(oldWidget);
// Xử lý khi widget được cập nhật
}

@override
void dispose() {
// Dọn dẹp tài nguyên
super.dispose();
}
}

2. Quản lý State

2.1. Local State

class _FormState extends State<FormWidget> {
final _formKey = GlobalKey<FormState>();
String _name = '';
String _email = '';

void _submitForm() {
if (_formKey.currentState!.validate()) {
setState(() {
// Cập nhật state
});
}
}

@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
onChanged: (value) {
setState(() {
_name = value;
});
},
),
TextFormField(
onChanged: (value) {
setState(() {
_email = value;
});
},
),
],
),
);
}
}

2.2. State với Animation

class _AnimatedWidgetState extends State<AnimatedWidget>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation;

@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 2),
vsync: this,
);
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.easeInOut,
);
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _animation,
child: YourWidget(),
);
}
}

3. Best Practices

3.1. Tối ưu hóa setState

class _OptimizedWidgetState extends State<OptimizedWidget> {
int _counter = 0;
bool _isLoading = false;

void _updateCounter() {
// Chỉ cập nhật các widget cần thiết
setState(() {
_counter++;
});
}

void _loadData() async {
setState(() {
_isLoading = true;
});

// Thực hiện tác vụ bất đồng bộ
await Future.delayed(Duration(seconds: 1));

setState(() {
_isLoading = false;
});
}
}

3.2. Xử lý State phức tạp

class _ComplexWidgetState extends State<ComplexWidget> {
// Sử dụng các biến riêng biệt cho từng loại state
int _counter = 0;
String _selectedItem = '';
List<String> _items = [];
bool _isLoading = false;

// Tách logic xử lý state
void _handleCounterChange() {
setState(() {
_counter++;
});
}

void _handleItemSelection(String item) {
setState(() {
_selectedItem = item;
});
}

Future<void> _loadItems() async {
setState(() {
_isLoading = true;
});

try {
final items = await fetchItems();
setState(() {
_items = items;
_isLoading = false;
});
} catch (e) {
setState(() {
_isLoading = false;
});
// Xử lý lỗi
}
}
}

4. Ví dụ thực tế

4.1. Form với Validation

class _LoginFormState extends State<LoginForm> {
final _formKey = GlobalKey<FormState>();
String _email = '';
String _password = '';
bool _isLoading = false;

Future<void> _submitForm() async {
if (_formKey.currentState!.validate()) {
setState(() {
_isLoading = true;
});

try {
await login(_email, _password);
// Xử lý đăng nhập thành công
} catch (e) {
// Xử lý lỗi
} finally {
setState(() {
_isLoading = false;
});
}
}
}

@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
onChanged: (value) => _email = value,
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter your email';
}
return null;
},
),
TextFormField(
onChanged: (value) => _password = value,
obscureText: true,
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter your password';
}
return null;
},
),
ElevatedButton(
onPressed: _isLoading ? null : _submitForm,
child: _isLoading
? CircularProgressIndicator()
: Text('Login'),
),
],
),
);
}
}

4.2. List với CRUD Operations

class _TodoListState extends State<TodoList> {
List<Todo> _todos = [];
bool _isLoading = false;

Future<void> _loadTodos() async {
setState(() {
_isLoading = true;
});

try {
final todos = await fetchTodos();
setState(() {
_todos = todos;
});
} finally {
setState(() {
_isLoading = false;
});
}
}

Future<void> _addTodo(Todo todo) async {
setState(() {
_todos.add(todo);
});
await saveTodo(todo);
}

Future<void> _updateTodo(Todo todo) async {
setState(() {
final index = _todos.indexWhere((t) => t.id == todo.id);
if (index != -1) {
_todos[index] = todo;
}
});
await updateTodo(todo);
}

Future<void> _deleteTodo(String id) async {
setState(() {
_todos.removeWhere((todo) => todo.id == id);
});
await deleteTodo(id);
}
}

Kết luận

Quản lý state trong StatefulWidget là một kỹ năng quan trọng trong phát triển ứng dụng Flutter. Việc hiểu rõ và áp dụng đúng cách sẽ giúp bạn tạo ra ứng dụng có hiệu suất tốt và dễ bảo trì.


Tài liệu tham khảo: