kaeru 0.1.7 copy "kaeru: ^0.1.7" to clipboard
kaeru: ^0.1.7 copied to clipboard

A powerful a comprehensive and efficient reactivity system for Flutter, inspired by Vue 3's @vue/reactivity.

Kaeru for Flutter #

Kaeru is a comprehensive and efficient reactivity system for Flutter, inspired by Vue 3's @vue/reactivity. It provides a fully functional reactive programming model that makes state management in Flutter simple, optimized, and declarative.

πŸš€ Features #

  • Fully reactive state management with Ref, Computed, AsyncComputed, and watchEffect.
  • Automatic dependency tracking for efficient updates.
  • Supports both synchronous and asynchronous computed values.
  • Optimized UI updates with Watch and KaeruMixin.
  • Seamless integration with ChangeNotifier and ValueNotifier.

πŸ“¦ Installation #

Add this package to your pubspec.yaml:

dependencies:
  kaeru:
    git:
      url: https://github.com/tachibana-shin/flutter_kaeru.git

Import it in your project:

import 'package:kaeru/kaeru.dart';

πŸ— API Documentation #

1️⃣ Reactive State: Ref<T> #

Represents a reactive variable that automatically triggers updates when changed.

Parameters:

Parameter Type Description
value T The initial value of the reactive reference.

Methods:

Method Returns Description
select<U>(U Function(T value)) Computed<U> Creates a computed value derived from this Ref<T>.

Example:

final count = Ref(0);
count.addListener(() {
  print("Count changed: ${count.value}");
});

count.value++;  // βœ… Triggers update

final doubleCount = count.select((v) => v * 2);
print(doubleCount.value); // βœ… 0
count.value = 5;
print(doubleCount.value); // βœ… 10

2️⃣ Derived State: Computed<T> #

Creates a computed value that automatically updates when dependencies change.

Parameters:

Parameter Type Description
getter T Function() A function that returns the computed value.

Methods:

Method Returns Description
select<U>(U Function(T value)) Computed<U> Creates a derived computed value.

Example:

final count = Ref(2);
final doubleCount = Computed(() => count.value * 2);

print(doubleCount.value); // βœ… 4
count.value++;
print(doubleCount.value); // βœ… 6

final tripleCount = doubleCount.select((v) => v * 1.5);
print(tripleCount.value); // βœ… 9

3️⃣ Effects: watchEffect & watch #

watchEffect(Function callback) -> VoidCallback

  • Automatically tracks dependencies and re-executes when values change.

Example:

final stop = watchEffect(() {
  print("Count is now: ${count.value}");
});

count.value++;  // βœ… Automatically tracks dependencies
stop(); // βœ… Stops watching

watch(List<ChangeNotifier> sources, Function callback, {bool immediate = false}) -> VoidCallback

  • Watches multiple ChangeNotifier sources.
  • If immediate = true, executes the callback immediately.

Example:

final stop = watch([count], () {
  print("Count changed: ${count.value}");
}, immediate: true);

stop(); // βœ… Stops watching

4️⃣ Asynchronous Derived State: AsyncComputed<T> #

Handles computed values that depend on asynchronous operations.

Parameters:

Parameter Type Description
getter Future<T> Function() A function returning a future value.
defaultValue T? An optional initial value before computation completes.
beforeUpdate T? Function() An optional function to run before updating the value.
notifyBeforeUpdate bool = true Whether to notify listeners before updating the value.
onError Function(dynamic error)? An optional error handler.
immediate bool Whether to compute immediately.

Example:

final asyncData = AsyncComputed(() async {
  await Future.delayed(Duration(seconds: 1));
  return "Loaded";
}, defaultValue: "Loading", onError: (e) => print("Error: $e"), immediate: true);

print(asyncData.value);  // βœ… "Loading"
await Future.delayed(Duration(seconds: 1));
print(asyncData.value);  // βœ… "Loaded"

5️⃣ UI Integration: KaeruMixin and Watch #

KaeruMixin (StatefulWidget Integration)

Allows stateful widgets to easily integrate with reactive values.

Example:

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> with KaeruMixin {
  late final Ref<int> count;

  @override
  void initState() {
    super.initState();
    count = ref(0);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Watch(() => Text("Count: ${count.value}")),
        ElevatedButton(
          onPressed: () => count.value++,
          child: Text("Increment"),
        ),
      ],
    );
  }
}

Watch (Automatic UI Rebuilds)

A widget that automatically updates when its dependencies change.

Example:

Watch(
  () => Text("Value: ${count.value}"),
)

6️⃣ Integration with ValueNotifier & ChangeNotifier #

ValueNotifier.toRef()

Converts a ValueNotifier<T> into a Ref<T>.

Example:

final valueNotifier = ValueNotifier(0);
final ref = valueNotifier.toRef();

ref.addListener(() {
  print("Updated: ${ref.value}");
});

valueNotifier.value = 10;  // βœ… Ref updates automatically

ValueNotifier Extension

Adds .toRef() to ValueNotifier to integrate seamlessly.


πŸ“Œ Kaeru Lifecycle & Listening Mixins #

KaeruLifeMixin and KaeruListenMixin are powerful mixins designed to simplify Flutter development by providing Vue-like lifecycle hooks and reactive state listening.

🎯 Why Use These Mixins? #

βœ… Cleaner code: No need to override multiple lifecycle methods or manage listeners manually. βœ… Reusable: Apply them to any StatefulWidget to enhance reactivity. βœ… Inspired by Vue: Provides a familiar development experience for reactive state management.

🟒 KaeruLifeMixin #

KaeruLifeMixin provides Vue-like lifecycle hooks for StatefulWidget. It enables multiple callbacks for different lifecycle events.

πŸš€ Features

  • onMounted(): Called when the widget is first created (initState).
  • onDependenciesChanged(): Called when dependencies change (didChangeDependencies).
  • onUpdated(): Called when the widget receives updated properties (didUpdateWidget).
  • onDeactivated(): Called when the widget is temporarily removed (deactivate).
  • onBeforeUnmount(): Called just before the widget is disposed (dispose).

πŸ“ Example Usage

class MyComponent extends StatefulWidget {
  @override
  _MyComponentState createState() => _MyComponentState();
}

class _MyComponentState extends State<MyComponent> with KaeruLifeMixin<MyComponent> {
  @override
  void initState() {
    super.initState();

    onMounted(() => print('βœ… Widget Mounted!'));
    onDependenciesChanged(() => print('πŸ”„ Dependencies Changed!'));
    onUpdated(() => print('♻️ Widget Updated!'));
    onDeactivated(() => print('⚠️ Widget Deactivated!'));
    onBeforeUnmount(() => print('πŸ—‘ Widget Disposed!'));
  }

  @override
  Widget build(BuildContext context) {
    return Text('KaeruLifeMixin Example');
  }
}

🟒 KaeruListenMixin #

KaeruListenMixin simplifies listening to ChangeNotifier updates within a StatefulWidget. It allows adding listeners dynamically and managing their cleanup automatically.

πŸš€ Features

  • listen(): Subscribes to a single ChangeNotifier and executes a callback when it changes.
  • listenAll(): Subscribes to multiple ChangeNotifiers with a single callback.
  • Returns a cancel function to remove listeners when necessary.

πŸ“ Example Usage

Listening to a Single Notifier
class MyNotifier extends ChangeNotifier {
  void update() {
    notifyListeners();
  }
}

class MyComponent extends StatefulWidget {
  @override
  _MyComponentState createState() => _MyComponentState();
}

class _MyComponentState extends State<MyComponent> with KaeruListenMixin<MyComponent> {
  final myNotifier = MyNotifier();
  VoidCallback? cancelListener;

  @override
  void initState() {
    super.initState();

    cancelListener = listen(myNotifier, () {
      print('Single notifier changed!');
    });
  }

  @override
  void dispose() {
    cancelListener?.call();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text('Listening to a single ChangeNotifier');
  }
}
Listening to Multiple Notifiers
class NotifierA extends ChangeNotifier {
  void update() => notifyListeners();
}

class NotifierB extends ChangeNotifier {
  void update() => notifyListeners();
}

class MyComponent extends StatefulWidget {
  @override
  _MyComponentState createState() => _MyComponentState();
}

class _MyComponentState extends State<MyComponent> with KaeruListenMixin<MyComponent> {
  final notifierA = NotifierA();
  final notifierB = NotifierB();
  VoidCallback? cancelListeners;

  @override
  void initState() {
    super.initState();

    cancelListeners = listenAll([notifierA, notifierB], () {
      print('One of the notifiers changed!');
    });
  }

  @override
  void dispose() {
    cancelListeners?.call();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text('Listening to multiple ChangeNotifiers');
  }
}

✨ Summary #

Feature KaeruLifeMixin KaeruListenMixin
Lifecycle Hooks βœ… Provides onMounted, onUpdated, onBeforeUnmount, etc. ❌ Not applicable
Reactive Listeners ❌ Not applicable βœ… Handles ChangeNotifier updates
Automatic Cleanup βœ… Hooks are executed at proper lifecycle stages βœ… Listeners are removed automatically
Code Simplicity βœ… Reduces the need for overriding multiple lifecycle methods βœ… Manages ChangeNotifier subscriptions easily

πŸš€ KaeruLifeMixin is perfect for handling widget lifecycle events. πŸ”„ KaeruListenMixin makes managing ChangeNotifier listeners easy.


🎯 API Summary #

Feature Supported
Ref<T> βœ…
Computed<T> βœ…
AsyncComputed<T> βœ…
watchEffect βœ…
watch βœ…
KaeruMixin βœ…
Watch Widget βœ…
ValueNotifier.toRef() βœ…
ReactiveNotifier<T> βœ…
VueNotifier.toRef() βœ…

This package provides an intuitive and efficient reactivity system for Flutter, making state management much easier and more performant. πŸš€

πŸ›  Contributing #

Pull requests and feature requests are welcome! Feel free to open an issue or contribute.

πŸ“œ License #

MIT License. See LICENSE for details.

1
likes
0
points
31
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful a comprehensive and efficient reactivity system for Flutter, inspired by Vue 3's @vue/reactivity.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, notifier_plus, plugin_platform_interface

More

Packages that depend on kaeru