Menu
CoddyTech

Pobierz raz w initState

Część sekcji Dane i sieć ścieżki Flutter w Coddy. Lekcja 7 z 27.

Flutter wywołuje build ponownie za każdym razem, gdy ekran jest odrysowywany: po każdym setState, gdy telefon się obraca, gdy zmienia się widget nadrzędny. Może się to zdarzać wiele razy na sekundę. build powinno tylko opisywać ekran, nigdy rozpoczynać żadnych działań.

Dlatego fetch umieszczone wewnątrz build uruchamia się ponownie przy każdym odrysowaniu. Każde uruchomienie to nowe żądanie do serwera, a ekran może nagle wyświetlić inną odpowiedź, choć nic jej nie zażądało:

// nowe żądanie przy każdym ponownym rysowaniu
FutureBuilder<String>(
  future: fetch('/tip'),
  ...
)

Utwórz obiekt future raz, gdy ekran się otworzy, w initState, i za każdym razem przekazuj tę samą wartość future do FutureBuilder:

late Future<String> _tip;

@override
void initState() {
  super.initState();
  _tip = fetch('/tip');
}

initState uruchamia się raz, przed pierwszym build. Rozpocznij je od super.initState();, tak jak wymaga tego Flutter.

challenge icon

Wyzwanie

Średni

Dotknij serca na górnym pasku: podpowiedź się zmienia, ponieważ fetch jest w build. Załaduj podpowiedź tylko raz:

  • dodaj late Future<String> _tip; do stanu
  • ustaw ją w initState za pomocą fetch('/tip')
  • przekaż _tip do FutureBuilder

Spróbuj swoich sił

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: TipScreen(),
    );
  }
}

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

  @override
  State<TipScreen> createState() => _TipScreenState();
}

class _TipScreenState extends State<TipScreen> {
  bool liked = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Tip of the Day'),
        actions: [
          IconButton(
            icon: Icon(liked ? Icons.favorite : Icons.favorite_border),
            onPressed: () {
              setState(() {
                liked = !liked;
              });
            },
          ),
        ],
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: FutureBuilder<String>(
              future: fetch('/tip'),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Text(
                    snapshot.data!,
                    textAlign: TextAlign.center,
                    style: const TextStyle(fontSize: 24),
                  );
                }
                return const CircularProgressIndicator();
              },
            ),
        ),
      ),
    );
  }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Dane i sieć

Poćwicz samodzielnie: Kompilator Flutter online