Menu
CoddyTech

Busque uma vez no initState

Parte da seção Dados e rede do Journey de Flutter da Coddy. Lição 7 de 27.

O Flutter chama build novamente sempre que a tela é redesenhada: após cada setState, quando o celular é girado, quando um widget pai muda. Isso pode acontecer muitas vezes por segundo. build deve apenas descrever a tela, nunca iniciar tarefas.

Por isso, um fetch escrito dentro de build é executado novamente a cada redesenho. Cada execução é uma nova solicitação ao servidor, e a tela pode mudar para uma resposta diferente sem que ninguém tenha pedido:

// uma nova requisição a cada redesenho
FutureBuilder<String>(
  future: fetch('/tip'),
  ...
)

Crie o future uma única vez, quando a tela abrir, em initState, e passe esse mesmo future para FutureBuilder todas as vezes:

late Future<String> _tip;

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

initState é executado uma vez, antes do primeiro build. Inicie-o com super.initState();, como o Flutter exige.

challenge icon

Desafio

Médio

Toque no coração na barra superior: a dica muda, porque o fetch está em build. Carregue a dica uma vez:

  • adicione late Future<String> _tip; ao estado
  • defina-o em initState com fetch('/tip')
  • passe _tip para o FutureBuilder

Experimente você mesmo

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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Dados e rede

Pratique por conta própria: Compilador de Flutter online