Skip to content

RtComponent

The RtComponent is a StatelessWidget hat simplifies the creation of reactive widgets by utilizing the dependency injection system. It provides features similar to RtProvider and RtConsumer that are used to inject and consume dependencies.

Syntax

abstract class RtComponent<T> extends StatelessWidget {
const RtComponent({Key? key}): super(key: key);
T Function()? get builder => null;
String? get id => null;
List<RtState> Function(T instance)? get listenStates => null;
bool get listenAll => false;
Widget render(BuildContext context, T inst);
}

Getters and Methods

  • builder: An optional function that creates an instance of the T dependency. This function is registered by Dependency Injection. If omitted, an attempt will be made to locate it within the closest ancestor where it was initially created.
  • id: An optional identifier for the T dependency. If omitted, the dependency will be located by its type( T ).
  • listenStates: An optional function for defining a list of the states that will rebuild the widget tree defined in the render method whenever it changes. It exposes the instance of the T dependency as argument of the function. If omitted, the listenAll getter is checked.
  • listenAll: A boolean value that determines whether to listen to all states( RtState ) of the T dependency for rebuilds the widget tree defined in the render method. For default, it is set to false .
  • render : A required function that builds the widget tree based on the instance of the T dependency. It receives the following arguments:
    • context: The BuildContext of the RtComponent widget.
    • inst: The instance of the T dependency.

Usage

In the following example demonstrates a reactive counter implementation using RtComponent .

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 CounterWithButtons extends RtComponent<CounterController> {
7
const CounterWithButtons({Key? key, this.id}) : super(key: key);
8
9
// Identify the `CounterController` dependency
10
@override
11
final String? id;
12
13
// Provide the `CounterController` dependency to the widget tree
14
@override
15
get builder => () => CounterController();
16
17
@override
18
Widget render(context, counterController) {
19
return Row(
20
mainAxisSize: MainAxisSize.min,
21
children: [
22
ElevatedButton(
23
onPressed: counterController.decrement,
24
child: const Icon(Icons.remove),
25
),
26
const SizedBox(width: 8),
27
Counter(id: id),
28
const SizedBox(width: 8),
29
ElevatedButton(
30
onPressed: counterController.increment,
31
child: const Icon(Icons.add),
32
),
33
],
34
);
35
}
36
}
1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
import 'counter_controller.dart';
4
5
class Counter extends RtComponent<CounterController> {
6
const Counter({Key? key, this.id}) : super(key: key);
7
8
// Identify the `CounterController` dependency
9
@override
10
final String? id;
11
12
// Provide the `CounterController` dependency to the widget tree
13
@override
14
get builder => () => CounterController();
15
16
// Observe the `count` property of the `counterController`
17
// and rebuild the widget tree when the `count` value changes
18
@override
19
get listenStates => (counterController) => [counterController.count];
20
21
@override
22
Widget render(context, counterController) {
23
return Text("${counterController.count}");
24
}
25
}
1
import 'package:flutter/material.dart';
2
import 'counter.dart';
3
import 'counter_with_buttons.dart';
4
5
class CounterView extends StatelessWidget {
6
const CounterView({Key? key}) : super(key: key);
7
8
@override
9
Widget build(BuildContext context) {
10
return Scaffold(
11
appBar: AppBar(
12
title: const Text('Counter'),
13
),
14
body: Center(
15
child: Column(
16
mainAxisSize: MainAxisSize.min,
17
children: const [
18
Text('Counter:'),
19
CounterWithButtons(),
20
SizedBox(height: 16),
21
Text('Counter with id:'),
22
CounterWithButtons(id: 'withId'),
23
],
24
),
25
),
26
floatingActionButton: const CircleAvatar(
27
child: Counter(),
28
),
29
);
30
}
31
}
1
import 'package:reactter/reactter.dart';
2
3
class CounterController {
4
// Create a reactive state using the `Signal` class
5
final count = Signal(0);
6
7
void increment() {
8
count.value++;
9
}
10
11
void decrement() {
12
count.value--;
13
}
14
}
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
}

In this example, we introduce two components: Counter and CounterWithButtons .

Counter listens changes in the count property of CounterController using the listenStates getter, and displays its value within the render method. On the other hand, CounterWithButtons provides buttons for incrementing and decrementing the counter and integrates the Counter component to display the count in its render method.

Both Counter and CounterWithButtons extend RtComponent with CounterController as their dependency, use the builder getter to create an instance of CounterController and the id getter to distinguish between different instances of the counter.