Skip to content

Lifecycle

In Reactter, both the states and the dependency (managed by the dependency injection) contain different stages, also known as Lifecycle . The lifecycle entails events emitted through the event handler.

Let’s explore the lifecycle events:

  • Lifecycle.registered: is triggered when the dependency has been registered.
  • Lifecycle.created: is triggered when the dependency instance has been created.
  • Lifecycle.willMount (exclusive of flutter_reactter package): is triggered when the dependency is going to be mounted in the widget tree.
  • Lifecycle.didMount (exclusive of flutter_reactter package): is triggered after the dependency has been successfully mounted in the widget tree.
  • Lifecycle.willUpdate: is triggered anytime the state or the dependency is about to be updated. The event parameter is a RtState .
  • Lifecycle.didUpdate: is triggered anytime the state or the dependency has been updated. The event parameter is a RtState .
  • Lifecycle.willUnmount(exclusive of flutter_reactter package): is triggered when the dependency is about to be unmounted from the widget tree.
  • Lifecycle.didUnmount(exclusive of flutter_reactter package): is triggered when the dependency has been successfully unmounted from the widget tree.
  • Lifecycle.deleted: is triggered when the dependency instance has been deleted.
  • Lifecycle.unregistered: is triggered when the dependency is no longer registered.

Using Event Handler

You can listen to the lifecycle events of a dependency using Rt.on or Rt.one method of the event handler. e.g:

1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
import 'counter.dart';
4
import 'counter_controller.dart';
5
6
class CounterView extends StatelessWidget {
7
const CounterView({Key? key}) : super(key: key);
8
9
@override
10
Widget build(BuildContext context) {
11
Rt.on(
12
RtDependency<CounterController>(),
13
Lifecycle.unregistered,
14
(_, __) => print('CounterController unregistered'),
15
);
16
17
Rt.on(
18
RtDependency<CounterController>(),
19
Lifecycle.registered,
20
(_, __) => print('CounterController registered'),
21
);
22
23
Rt.on(
24
RtDependency<CounterController>(),
25
Lifecycle.created,
26
(_, __) => print('CounterController created'),
27
);
28
29
Rt.on(
30
RtDependency<CounterController>(),
31
Lifecycle.deleted,
32
(_, __) => print('CounterController deleted'),
33
);
27 collapsed lines
34
35
final showCounter = Signal(false);
36
37
return Scaffold(
38
appBar: AppBar(
39
title: const Text("Counter - Lifecycle using EventHandler"),
40
),
41
body: RtSignalWatcher(
42
builder: (context, child) {
43
return Center(
44
child: Column(
45
mainAxisAlignment: MainAxisAlignment.center,
46
children: [
47
ElevatedButton(
48
onPressed: () => showCounter(!showCounter.value),
49
child: showCounter.value
50
? const Text('Hide counter')
51
: const Text('Show Counter'),
52
),
53
const SizedBox(height: 8),
54
if (showCounter.value) const Counter(),
55
],
56
),
57
);
58
},
59
),
60
);
61
}
62
}
1
import 'package:flutter_reactter/flutter_reactter.dart';
2
3
class CounterController {
4
final count = Signal(0);
5
6
CounterController() {
7
Rt.on(this, Lifecycle.willMount, (_, __) {
8
print('CounterController will mount');
9
});
10
11
Rt.on(this, Lifecycle.didMount, (_, __) {
12
print('CounterController did mount');
13
});
14
15
Rt.on(this, Lifecycle.willUpdate, (_, state) {
16
print('CounterController will update by ${state.runtimeType}');
17
});
18
19
Rt.on(this, Lifecycle.didUpdate, (_, state) {
20
print('CounterController did updated by ${state.runtimeType}');
21
});
22
23
Rt.on(this, Lifecycle.willUnmount, (_, __) {
24
print('CounterController will unmount');
25
});
26
27
Rt.on(this, Lifecycle.didUnmount, (_, __) {
28
print('CounterController did unmount');
29
});
30
}
31
32
void increment() {
33
count.value++;
34
}
35
36
void decrement() {
37
count.value--;
38
}
39
}
1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
4
import 'counter_controller.dart';
5
6
class Counter extends StatelessWidget {
7
const Counter({Key? key}) : super(key: key);
8
9
@override
10
Widget build(BuildContext context) {
11
// Provide the `CounterController` dependency to the widget tree
12
return RtProvider<CounterController>(
13
() => CounterController(),
14
builder: (context, counterController, child) {
15
return Row(
16
mainAxisSize: MainAxisSize.min,
17
children: [
18
ElevatedButton(
19
onPressed: counterController.decrement,
20
child: const Icon(Icons.remove),
21
),
22
const SizedBox(width: 8),
23
// Observe the `count` property of the `counterController`
24
// and rebuild the widget tree when the `count` value changes
25
RtConsumer<CounterController>(
26
listenStates: (counterController) => [counterController.count],
27
builder: (context, counterController, child) {
28
return Text("${counterController.count}");
29
},
30
),
31
const SizedBox(width: 8),
32
ElevatedButton(
33
onPressed: counterController.increment,
34
child: const Icon(Icons.add),
35
),
36
],
37
);
38
},
39
);
40
}
41
}
1
import 'package:flutter/material.dart';
2
import 'counter_view.dart';
3
4
void main() {
5
runApp(MyApp());
6
}
7
8
class MyApp extends StatelessWidget {
9
@override
10
Widget build(BuildContext context) {
11
return MaterialApp(
12
home: CounterView(),
13
);
14
}
15
}

Using LifecycleObserver

Extend your instances with LifecycleObserver and use its methods to observe the lifecycle events. e.g:

1
import 'package:flutter_reactter/flutter_reactter.dart';
2
3
class CounterController extends LifecycleObserver {
4
final count = Signal(0);
5
6
void onInitialized() {
7
print('CounterController initialized');
8
}
9
10
void onDidMount() {
11
print('CounterController mounted');
12
}
13
14
void onWillMount() {
15
print('CounterController will mount');
16
}
17
18
void onWillUpdate(RtState state) {
19
print('CounterController will update by ${state.runtimeType}');
20
}
21
22
void onDidUpdate(RtState state) {
23
print('CounterController did update by ${state.runtimeType}');
24
}
25
26
void onWillUnmount() {
27
print('CounterController will unmount');
28
}
29
30
void onDidUnmount() {
31
print('CounterController did unmount');
32
}
33
34
void increment() {
35
count.value++;
36
}
37
38
void decrement() {
39
count.value--;
40
}
41
}
1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
import 'counter.dart';
4
5
class CounterView extends StatelessWidget {
6
const CounterView({Key? key}) : super(key: key);
7
8
@override
9
Widget build(BuildContext context) {
10
final showCounter = Signal(false);
11
12
return Scaffold(
13
appBar: AppBar(
14
title: const Text("Counter - Lifecycle using LifecycleObserver"),
15
),
16
body: RtSignalWatcher(
17
builder: (context, child) {
18
return Center(
19
child: Column(
20
mainAxisAlignment: MainAxisAlignment.center,
21
children: [
22
ElevatedButton(
23
onPressed: () => showCounter(!showCounter.value),
24
child: showCounter.value
25
? const Text('Hide counter')
26
: const Text('Show Counter'),
27
),
28
const SizedBox(height: 8),
29
if (showCounter.value) const Counter(),
30
],
31
),
32
);
33
},
34
),
35
);
36
}
37
}
1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
4
import 'counter_controller.dart';
5
6
class Counter extends StatelessWidget {
7
const Counter({Key? key}) : super(key: key);
8
9
@override
10
Widget build(BuildContext context) {
11
// Provide the `CounterController` dependency to the widget tree
12
return RtProvider<CounterController>(
13
() => CounterController(),
14
builder: (context, counterController, child) {
15
return Row(
16
mainAxisSize: MainAxisSize.min,
17
children: [
18
ElevatedButton(
19
onPressed: counterController.decrement,
20
child: const Icon(Icons.remove),
21
),
22
const SizedBox(width: 8),
23
// Observe the `count` property of the `counterController`
24
// and rebuild the widget tree when the `count` value changes
25
RtConsumer<CounterController>(
26
listenStates: (counterController) => [counterController.count],
27
builder: (context, counterController, child) {
28
return Text("${counterController.count}");
29
},
30
),
31
const SizedBox(width: 8),
32
ElevatedButton(
33
onPressed: counterController.increment,
34
child: const Icon(Icons.add),
35
),
36
],
37
);
38
},
39
);
40
}
41
}
1
import 'package:flutter/material.dart';
2
import 'counter_view.dart';
3
4
void main() {
5
runApp(MyApp());
6
}
7
8
class MyApp extends StatelessWidget {
9
@override
10
Widget build(BuildContext context) {
11
return MaterialApp(
12
home: CounterView(),
13
);
14
}
15
}

Using UseEffect

The UseEffect hook can be used to listen to the lifecycle events of a dependency. e.g:

1
import 'package:flutter_reactter/flutter_reactter.dart';
2
3
class CounterController {
4
final count = Signal(0);
5
6
CounterController() {
7
UseEffect(() {
8
print('CounterController mounted');
9
10
return () {
11
print('CounterController will unmount');
12
};
13
}, []);
14
15
UseEffect(() {
16
print(
17
"CounterController's count changed to ${count.value}",
18
);
19
}, [count]);
20
}
21
22
void increment() {
23
count.value++;
24
}
25
26
void decrement() {
27
count.value--;
28
}
29
}
1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
import 'counter.dart';
4
5
class CounterView extends StatelessWidget {
6
const CounterView({Key? key}) : super(key: key);
7
8
@override
9
Widget build(BuildContext context) {
10
final showCounter = Signal(false);
11
12
return Scaffold(
13
appBar: AppBar(
14
title: const Text("Counter - Lifecycle using UseEffect"),
15
),
16
body: RtSignalWatcher(
17
builder: (context, child) {
18
return Center(
19
child: Column(
20
mainAxisAlignment: MainAxisAlignment.center,
21
children: [
22
ElevatedButton(
23
onPressed: () => showCounter(!showCounter.value),
24
child: showCounter.value
25
? const Text('Hide counter')
26
: const Text('Show Counter'),
27
),
28
const SizedBox(height: 8),
29
if (showCounter.value) const Counter(),
30
],
31
),
32
);
33
},
34
),
35
);
36
}
37
}
1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
4
import 'counter_controller.dart';
5
6
class Counter extends StatelessWidget {
7
const Counter({Key? key}) : super(key: key);
8
9
@override
10
Widget build(BuildContext context) {
11
// Provide the `CounterController` dependency to the widget tree
12
return RtProvider<CounterController>(
13
() => CounterController(),
14
builder: (context, counterController, child) {
15
return Row(
16
mainAxisSize: MainAxisSize.min,
17
children: [
18
ElevatedButton(
19
onPressed: counterController.decrement,
20
child: const Icon(Icons.remove),
21
),
22
const SizedBox(width: 8),
23
// Observe the `count` property of the `counterController`
24
// and rebuild the widget tree when the `count` value changes
25
RtConsumer<CounterController>(
26
listenStates: (counterController) => [counterController.count],
27
builder: (context, counterController, child) {
28
return Text("${counterController.count}");
29
},
30
),
31
const SizedBox(width: 8),
32
ElevatedButton(
33
onPressed: counterController.increment,
34
child: const Icon(Icons.add),
35
),
36
],
37
);
38
},
39
);
40
}
41
}
1
import 'package:flutter/material.dart';
2
import 'counter_view.dart';
3
4
void main() {
5
runApp(MyApp());
6
}
7
8
class MyApp extends StatelessWidget {
9
@override
10
Widget build(BuildContext context) {
11
return MaterialApp(
12
home: CounterView(),
13
);
14
}
15
}