reactive_notify 2.1.3 copy "reactive_notify: ^2.1.3" to clipboard
reactive_notify: ^2.1.3 copied to clipboard

discontinuedreplaced by: reactive_notifier

A Dart library for managing reactive state efficiently, supporting multiple independent instances with unique keys.

ReactiveNotify #

A powerful, elegant, and type-safe state management solution for Flutter that seamlessly integrates with the MVVM pattern while maintaining complete independence from BuildContext. Perfect for applications of any size.

pub package likes popularity license


πŸ“’ Important Notice: Renamed to ReactiveNotifier #

We’ve renamed this package to reactive_notifier to better align with naming conventions and improve clarity. reactive_notify is now deprecated, and we strongly recommend transitioning to the updated package for future projects.

State of the Libraries #

Package Status Version
reactive_notify Deprecated pub package
reactive_notifier Active pub package

The API remains unchanged, so you can upgrade to reactive_notifier seamlessly by simply updating your dependencies.

dependencies:
  reactive_notifier: latest # See version badge above
copied to clipboard

Features #

  • πŸš€ Simple and intuitive API
  • πŸ—οΈ Perfect for MVVM architecture
  • πŸ”„ Independent from BuildContext
  • 🎯 Type-safe state management
  • πŸ“‘ Built-in Async and Stream support
  • πŸ”— Smart related states system
  • πŸ› οΈ Repository/Service layer integration
  • ⚑ High performance with minimal rebuilds
  • πŸ› Powerful debugging tools
  • πŸ“Š Detailed error reporting

Table of Contents #

Installation #

To continue using the deprecated package:

dependencies:
  reactive_notify: ^2.1.3
copied to clipboard

To switch to the updated version:

dependencies:
  reactive_notifier: latest # See version badge above
copied to clipboard

Quick Start #

Note: All examples in this documentation are compatible with both reactive_notify and reactive_notifier.

Basic Usage #

// Define states globally or in a mixin
final counterState = ReactiveNotify<int>(() => 0);

// Using a mixin (recommended for organization)
mixin AppStateMixin {
  static final counterState = ReactiveNotify<int>(() => 0);
  static final userState = ReactiveNotify<UserState>(() => UserState());
}

// Use in widgets - No BuildContext needed for state management!
class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ReactiveBuilder<int>(
      valueListenable: AppStateMixin.counterState,
      builder: (context, value, keep) {
        return Column(
          children: [
            Text('Count: $value'),
            keep(const CounterButtons()), // Static content preserved
          ],
        );
      },
    );
  }
}
copied to clipboard

State Management Patterns #

Global State Declaration #

// βœ… Correct: Global state declaration
final userState = ReactiveNotify<UserState>(() => UserState());

// βœ… Correct: Mixin with static states
mixin AuthStateMixin {
  static final authState = ReactiveNotify<AuthState>(() => AuthState());
  static final sessionState = ReactiveNotify<SessionState>(() => SessionState());
}

// ❌ Incorrect: Never create inside widgets
class WrongWidget extends StatelessWidget {
  final state = ReactiveNotify<int>(() => 0); // Don't do this!
}
copied to clipboard

MVVM Integration #

ReactiveNotify is built with MVVM in mind:

// 1. Repository Layer
class UserRepository implements RepositoryImpl<User> {
  final ApiNotifier apiNotifier;
  UserRepository(this.apiNotifier);
  
  Future<User> getUser() async => // Implementation
}

// 2. Service Layer (Alternative to Repository)
class UserService implements ServiceImpl<User> {
  Future<User> getUser() async => // Implementation
}

// 3. ViewModel
class UserViewModel extends ViewModelImpl<UserState> {
  UserViewModel(UserRepository repository) 
    : super(repository, UserState(), 'user-vm', 'UserScreen');
    
  @override
  void init() {
    // Automatically called on initialization
    loadUser();
  }
  
  Future<void> loadUser() async {
    try {
      final user = await repository.getUser();
      setState(UserState(name: user.name, isLoggedIn: true));
    } catch (e) {
      // Error handling
    }
  }
}

// 4. Create ViewModel Notifier
final userNotifier = ReactiveNotify<UserViewModel>(() {
  final repository = UserRepository(apiNotifier);
  return UserViewModel(repository);
});

// 5. Use in View
class UserScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ReactiveBuilder<UserViewModel>(
      valueListenable: userNotifier,
      builder: (_, viewModel, keep) {
        return Column(
          children: [
            Text('Welcome ${viewModel.state.name}'),
            keep(const UserActions()),
          ],
        );
      },
    );
  }
}
copied to clipboard

Correct Pattern #

// 1. Define individual states
final userState = ReactiveNotify<UserState>(() => UserState());
final cartState = ReactiveNotify<CartState>(() => CartState());
final settingsState = ReactiveNotify<SettingsState>(() => SettingsState());

// 2. Create relationships correctly
final appState = ReactiveNotify<AppState>(
  () => AppState(),
  related: [userState, cartState, settingsState]
);

// 3. Use in widgets - Updates automatically when any related state changes
class AppDashboard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ReactiveBuilder<AppState>(
      valueListenable: appState,
      builder: (context, state, keep) {
        // Access related states directly
        final user = appState.from<UserState>();
        final cart = appState.from<CartState>(cartState.keyNotifier);
        
        return Column(
          children: [
            Text('Welcome ${user.name}'),
            Text('Cart Items: ${cart.items.length}'),
            if (user.isLoggedIn) keep(const UserProfile())
          ],
        );
      },
    );
  }
}
copied to clipboard

What to Avoid #

// ❌ NEVER: Nested related states
final cartState = ReactiveNotify<CartState>(
  () => CartState(),
  related: [userState] // ❌ Don't do this
);

// ❌ NEVER: Chain of related states
final orderState = ReactiveNotify<OrderState>(
  () => OrderState(),
  related: [cartState] // ❌ Avoid relation chains
);

// βœ… CORRECT: Flat structure with single parent
final appState = ReactiveNotify<AppState>(
  () => AppState(),
  related: [userState, cartState, orderState]
);
copied to clipboard

Async & Stream Support #

Async Operations #

class ProductViewModel extends AsyncViewModelImpl<List<Product>> {
  @override
  Future<List<Product>> fetchData() async {
    return await repository.getProducts();
  }
}

class ProductsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ReactiveAsyncBuilder<List<Product>>(
      viewModel: productViewModel,
      buildSuccess: (products) => ProductGrid(products),
      buildLoading: () => const LoadingSpinner(),
      buildError: (error, stack) => ErrorWidget(error),
      buildInitial: () => const InitialView(),
    );
  }
}
copied to clipboard

Stream Handling #

final messagesStream = ReactiveNotify<Stream<Message>>(
  () => messageRepository.getMessageStream()
);

class ChatScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ReactiveStreamBuilder<Message>(
      streamNotifier: messagesStream,
      buildData: (message) => MessageBubble(message),
      buildLoading: () => const LoadingIndicator(),
      buildError: (error) => ErrorMessage(error),
      buildEmpty: () => const NoMessages(),
      buildDone: () => const StreamComplete(),
    );
  }
}
copied to clipboard

Debugging System #

ReactiveNotify includes a comprehensive debugging system with detailed error messages:

Creation Tracking #

πŸ“¦ Creating ReactiveNotify<UserState>
πŸ”— With related types: CartState, OrderState
copied to clipboard

Invalid Structure Detection #

⚠️ Invalid Reference Structure Detected!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Current Notifier: CartState
Key: cart_key
Problem: Attempting to create a notifier with an existing key
Solution: Ensure unique keys for each notifier
Location: package:my_app/cart/cart_state.dart:42
copied to clipboard

Performance Monitoring #

⚠️ Notification Overflow Detected!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Notifier: CartState
50 notifications in 500ms
❌ Problem: Excessive updates detected
βœ… Solution: Review update logic and consider debouncing
copied to clipboard

And more...

Best Practices #

State Declaration #

  • Declare ReactiveNotify instances globally or as static mixin members
  • Never create instances inside widgets
  • Use mixins for better organization of related states

Performance Optimization #

  • Use keep for static content
  • Maintain flat state hierarchy
  • Use keyNotifier for specific state access
  • Avoid unnecessary rebuilds

Architecture Guidelines #

  • Follow MVVM pattern
  • Utilize Repository/Service patterns
  • Let ViewModels initialize automatically
  • Keep state updates context-independent
  • Maintain flat relationships
  • Avoid circular dependencies
  • Use type-safe access
  • Keep state updates predictable

Coming Soon: Real-Time State Inspector πŸ” #

We're developing a powerful visual debugging interface that will revolutionize how you debug and monitor ReactiveNotify states:

Features in Development #

  • πŸ“Š Real-time state visualization
  • πŸ”„ Live update tracking
  • πŸ“ˆ Performance metrics
  • πŸ•ΈοΈ Interactive dependency graph
  • ⏱️ Update timeline
  • πŸ” Deep state inspection
  • πŸ“± DevTools integration

This tool will help you:

  • Understand state flow in real-time
  • Identify performance bottlenecks
  • Debug complex state relationships
  • Monitor rebuild patterns
  • Optimize your application
  • Develop more efficiently

Stay tuned for this exciting addition to ReactiveNotify!

Contributing #

We welcome contributions! See our Contributing Guide for details.

Star Us! ⭐ #

If you find ReactiveNotify helpful, please star us on GitHub! It helps other developers discover this package.

License #

MIT License - see the LICENSE file for details

3
likes
160
points
27
downloads

Publisher

verified publisherjhonacode.com

Weekly Downloads

2024.07.09 - 2025.01.21

A Dart library for managing reactive state efficiently, supporting multiple independent instances with unique keys.

Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on reactive_notify