Menu
CoddyTech

Nút thử lại

Thuộc phần Dữ liệu và mạng trong hành trình Flutter của Coddy. Bài học 14 trên 27.

Kết nối sẽ hoạt động lại. Màn hình báo lỗi tốt không khiến người dùng mắc kẹt: màn hình cho biết chuyện gì đã xảy ra và đưa ra cách thử lại.

Thử lại nghĩa là tải lại: tạo một tác vụ bất đồng bộ mới trong setState, giống như nút làm mới.

void tryAgain() {
  setState(() {
    _message = fetch('/message');
  });
}

Có một chi tiết cần lưu ý. Trong khi tác vụ bất đồng bộ mới đang chạy, snapshot vẫn giữ lỗi gần nhất, giống như cách nó giữ dữ liệu cũ: hasError vẫn là true cho đến khi câu trả lời mới xuất hiện. Để hiển thị vòng xoay trong lần thử thứ hai, hãy kiểm tra snapshot.connectionState trước:

if (snapshot.connectionState == ConnectionState.waiting) {
  return const CircularProgressIndicator();
}
if (snapshot.hasError) {
  // lỗi và nút bấm
}
return Text(snapshot.data!);

Để xem lỗi trong bản xem trước, hãy viết offline = true; ở dòng đầu tiên của main rồi nhấn Chạy. offline đến từ api.dart: nó khiến mọi lệnh gọi đều thất bại như thể điện thoại không có sóng. Xóa dòng đó trước khi nhấn Kiểm tra.

challenge icon

Thử thách

Trung bình

Thêm cách xử lý khi gặp lỗi:

  • thêm nút Try again bên dưới dòng thông báo lỗi
  • khi nhấn nút, gọi fetch('/message') mới trong setState
  • vòng tròn tải sẽ hiển thị trong lúc thử lại: kiểm tra ConnectionState.waiting trước tiên trong builder

Tự làm thử

import 'package:flutter/material.dart';

import 'api.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MessageScreen(),
    );
  }
}

class MessageScreen extends StatefulWidget {
  const MessageScreen({super.key});

  @override
  State<MessageScreen> createState() => _MessageScreenState();
}

class _MessageScreenState extends State<MessageScreen> {
  late Future<String> _message;

  @override
  void initState() {
    super.initState();
    _message = fetch('/message');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<String>(
          future: _message,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text(
                'Could not load: ${snapshot.error}',
                style: const TextStyle(fontSize: 20),
              );
            }
            if (snapshot.hasData) {
              return Text(snapshot.data!, style: const TextStyle(fontSize: 24));
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Dữ liệu và mạng

Tự luyện tập: Trình biên dịch Flutter online