Start with a counter
Fundamentals: Observable + Action + Observer. Run this example to see the dependency relationships change in real Flutter widgets.
Try the real Flutter example.
The Flutter runtime loads when you press Run.Flutter widgets · flutter_mobx
Try it
Increment and reset. The observable drives one small Observer.
How it works
The source below is the code compiled into the live example. Each route owns its widget state; leaving a route disposes its effects and subscriptions. Cart and task state are shared by the gallery engine for cross-view demonstrations.
dart
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../site/stores.dart';
Widget buildExample(DemoStores stores) => const CounterExample();
class CounterExample extends StatefulWidget {
const CounterExample({super.key});
@override
State<CounterExample> createState() => _CounterExampleState();
}
class _CounterExampleState extends State<CounterExample> {
final count = Observable(0);
@override
Widget build(BuildContext context) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'A little change.',
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 16),
const Text(
'The Observer reads count. Tap the button: only that number needs to rebuild.',
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 32),
child: Observer(
builder: (_) => Text(
'${count.value}',
style: Theme.of(context).textTheme.displayLarge,
),
),
),
FilledButton.icon(
onPressed: () => runInAction(() => count.value++),
icon: const Icon(LucideIcons.plus),
label: const Text('Add one'),
),
TextButton(
onPressed: () => runInAction(() => count.value = 0),
child: const Text('Reset'),
),
],
);
}Browse all examples · Application architecture · API families