Como o InheritedWidget consertou meu app Flutter super-engenheirado.
Você já usou Theme.of(context) ou MediaQuery.of(context)?
Pois é… isso é o InheritedWidget disfarçado.
Eu costumava recorrer ao Provider no exato momento em que precisava de um estado compartilhado. Então, um dia — no meio de um colapso durante um debug — eu trombei com o InheritedWidget. Descobri que a coisa que eu vinha evitando era exatamente a ferramenta que o Flutter tinha me dado o tempo todo.
Sem pacotes extras. Sem mágica. Apenas… genialidade nativa.
O que é, afinal, o InheritedWidget?
Em sua essência, o InheritedWidget é a forma nativa do Flutter de compartilhar dados árvore abaixo — sem precisar passar esses dados por cada construtor, como se fosse a conta de um jantar em grupo onde só você tem uma calculadora.
Ele funciona da seguinte forma:
- Envolve uma parte da sua árvore de widgets.
- Permite que os filhos acessem os dados via
.of(context). - Notifica apenas os widgets que realmente se importam quando algo muda.
Ah, e aqui está o segredo: o Flutter usa isso internamente o tempo todo para gerenciar o estado — no Theme, MediaQuery, Navigator, Directionality e em uma dúzia de outros lugares nos quais você provavelmente confia diariamente.
Então, sim… ele é algo bem importante.
Minha configuração exagerada (Antes do InheritedWidget):
- Instalei o Provider.
- Criei um
ChangeNotifierpara uma única string. - Envolvi tudo em um
MultiProvider(sem motivo nenhum). - Adicionei widgets
Consumercomo se fossem confetes. - Esquecia o
notifyListeners()constantemente.
Tudo isso… apenas para atualizar um nome de usuário.
Eu basicamente construí o sistema de lançamento da NASA apenas para exibir um ‘Olá, Cap’. Funcionou — mas a sensação era a de entregar uma pizza usando um foguete.
A solução com InheritedWidget (Depois):
class UserData extends InheritedWidget {
final String name;
const UserData({
required this.name,
required Widget child,
}) : super(child: child);
static UserData of(BuildContext context) {
final UserData? result =
context.dependOnInheritedWidgetOfExactType<UserData>();
assert(result != null, 'No UserData found in context');
return result!;
}
@override
bool updateShouldNotify(UserData old) => name != old.name;
}
Use-o:
Text(UserData.of(context).name);
Quando usar (e quando fugir)
Use o InheritedWidget quando:
- Você precisa compartilhar dados árvore abaixo (tema, configurações, estado).
- Os dados mudam com pouca frequência.
- Você quer uma configuração super leve.
Evite se:
- Seu estado for assíncrono, aninhado ou complexo.
- Você precisar de atualizações granulares em widgets não relacionados.
- Você odeia o
updateShouldNotify(embora ele não seja tão assustador assim).
Sinceramente, isso me lembrou daquelas vezes em que você gasta 3 horas configurando Bloc ou Cubit apenas para perceber: “Droga. Eu poderia ter usado apenas um setState() e ido dar uma volta lá fora.”
Às vezes, as ferramentas mais simples não são apenas o suficiente — elas são melhores.
O InheritedWidget é esse tipo de simplicidade. É como o setState(), mas para quando sua árvore de widgets precisa “ouvir” sem precisar “gritar”.
Então, aqui está a regra pela qual eu vivo agora: Use o InheritedWidget quando seus dados forem simples, mas precisarem ser compartilhados entre vários widgets.
Sem mágica. Sem código repetitivo (boilerplate). Apenas poder nativo e limpo — do jeito Flutter de ser.