What is reactive programming ?

Answer

Overview

Reactive programming is a programming paradigm that focuses on data streams and the propagation of change. Instead of imperatively asking "what is the value?" you declare "when the value changes, do this."

Think of a spreadsheet — when you change cell A1, cell B1 that depends on A1 automatically updates. That's reactive.


Core Concepts

ConceptDescription
Observable/StreamSource of data/events over time
Observer/ListenerReacts when data changes
  • Subscription | Connection between observer and observable | | Operator | Transform, filter, combine streams |

Reactive vs Imperative

dart
// ─── Imperative approach ──────────────────────────────
int a = 5;
int b = 10;
int sum = a + b; // sum = 15

a = 20;
// sum is still 15 — must manually recalculate

// ─── Reactive approach ────────────────────────────────
final aStream = BehaviorSubject<int>.seeded(5);
final bStream = BehaviorSubject<int>.seeded(10);

final sumStream = Rx.combineLatest2(aStream, bStream, (a, b) => a + b);

sumStream.listen((sum) => print('Sum: $sum')); // Auto-updates!

aStream.add(20); // sum automatically becomes 30

Reactive Programming in Flutter

Flutter's entire UI model is reactive — widgets rebuild automatically when state changes.

1. Streams + StreamBuilder

dart
class ReactiveCounter extends StatefulWidget {
  
  _ReactiveCounterState createState() => _ReactiveCounterState();
}

class _ReactiveCounterState extends State<ReactiveCounter> {
  final StreamController<int> _counter = StreamController<int>.broadcast();
  int _count = 0;

  void _increment() => _counter.sink.add(++_count);

  
  void dispose() {
    _counter.close();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        StreamBuilder<int>(
          stream: _counter.stream,
          initialData: 0,
          builder: (context, snapshot) => Text('Count: ${snapshot.data}'),
        ),
        ElevatedButton(onPressed: _increment, child: Text('Increment')),
      ],
    );
  }
}

2. ChangeNotifier (SimpleReactive)

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

  void increment() {
    _count++;
    notifyListeners(); // Notifies all listeners reactively
  }
}

// Widget auto-rebuilds when count changes
Consumer<CounterModel>(
  builder: (context, model, child) => Text('${model.count}'),
)

3. BLoC Pattern (Reactive Architecture)

dart
class CounterBloc {
  final _countController = StreamController<int>();
  Stream<int> get countStream => _countController.stream;

  int _count = 0;

  void increment() => _countController.sink.add(++_count);
  void dispose() => _countController.close();
}

rxdart (Reactive Extensions for Dart)

dart
import 'package:rxdart/rxdart.dart';

final subject = BehaviorSubject<String>();

// Reactive search with debounce + distinct
subject.stream
    .distinct()
    .debounceTime(Duration(milliseconds: 300))
    .switchMap((query) => searchApi(query))
    .listen((results) => print(results));

Key Reactive Operators

OperatorDescription
text
map
Transform each event
text
filter/where
Only pass events that match
text
debounceTime
Wait for pause before emitting
text
distinct
Only emit if value changed
text
switchMap
Cancel previous and switch to new stream
text
combineLatest
Combine multiple streams
text
merge
Merge multiple streams into one

Benefits of Reactive Programming

  • ✅ Declarative — describe what to do, not how
  • ✅ Automatic UI updates when state changes
  • ✅ Easy to compose and transform data
  • ✅ Handles async events naturally
  • ✅ Decoupled components

Flutter Connection: Flutter itself is a reactive framework.

text
setState
,
text
ChangeNotifier
,
text
BLoC
,
text
Riverpod
— all follow reactive principles. The widget tree "reacts" to state changes automatically.