Crear un holder o context en Flutter

Tiempo de lectura: 2 minutos

En Flutter no tiene React Hooks (como react native), pero sí tiene un árbol de widgets donde puedes inyectar datos desde arriba hacia abajo.

Otoño -pexels

1. Usar InheritedWidget (nativo de Flutter)

Es el equivalente “puro” al React Context, aunque más bajo nivel.

Ejemplo básico:

import 'package:flutter/material.dart';

class CounterHolder extends InheritedWidget {
  final int counter;
  final Function() increment;

  const CounterHolder({
    Key? key,
    required this.counter,
    required this.increment,
    required Widget child,
  }) : super(key: key, child: child);

  static CounterHolder of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<CounterHolder>()!;
  }

  @override
  bool updateShouldNotify(CounterHolder oldWidget) {
    return counter != oldWidget.counter;
  }
}

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

  @override
  State<CounterApp> createState() => _CounterAppState();
}

class _CounterAppState extends State<CounterApp> {
  int counter = 0;

  void increment() {
    setState(() => counter++);
  }

  @override
  Widget build(BuildContext context) {
    return CounterHolder(
      counter: counter,
      increment: increment,
      child: Scaffold(
        appBar: AppBar(title: const Text('Counter Holder')),
        body: Center(child: Text('Valor: $counter')),
        floatingActionButton: FloatingActionButton(
          onPressed: CounterHolder.of(context).increment,
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

Esto sería lo más parecido a un Context.Provider y useContext de React.

2. Usar Provider (paquete más popular)

👉 Este es el estándar moderno y el más parecido al “Context + Hooks” de React.

# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  provider: ^6.1.2

Ejemplo:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class CounterModel with ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => CounterModel(),
      child: const MyApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text("Provider Example")),
        body: Center(
          child: Text(
            'Count: ${context.watch<CounterModel>().count}',
            style: const TextStyle(fontSize: 30),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => context.read<CounterModel>().increment(),
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

🔹 ChangeNotifierProvider → sería como tu “Context Provider”.
🔹 context.watch<T>() → sería como useContext() que escucha cambios.
🔹 context.read<T>() → accede al valor sin escuchar cambios (como un useRef o dispatch).

3. Otras opciones más potentes

Si en React usabas algo como Redux o Zustand, en Flutter puedes usar:

  • Riverpod → Más moderno y sin dependencias de BuildContext.
  • Bloc / Cubit → Ideal para arquitecturas limpias y grandes apps.
  • GetX o MobX → Alternativas reactivas más sencillas.

Deja un comentario