reactive_notifier 2.2.1 copy "reactive_notifier: ^2.2.1" to clipboard
reactive_notifier: ^2.2.1 copied to clipboard

A Dart library for managing reactive state efficiently, supporting multiples related state.

ReactiveNotifier #

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

reactive_notifier

Dart SDK Version Flutter Platform pub package likes popularity

License: MIT CI

Note: Are you migrating from reactive_notify? The API remains unchanged - just update your dependency to reactive_notifier.

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

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  reactive_notifier: ^2.2.1
copied to clipboard

Quick Start #

Basic Usage #

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

// Using a mixin (recommended for organization)
mixin AppStateMixin {
  static final counterState = ReactiveNotifier<int>(() => 0);
  static final userState = ReactiveNotifier<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 = ReactiveNotifier<UserState>(() => UserState());

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

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

MVVM Integration #

ReactiveNotifier 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
    }
  }
}

// Without Repository If you need to handle other types of logic or use external Notifiers too.
class SimpleViewModel extends ViewModelStateImpl<UserState> {
  SimpleViewModel(): super(UserState());

  void updateUser(String name) {
    updateState(UserState(name: name));
  }
}

// 4. Create ViewModel Notifier
final userNotifier = ReactiveNotifier<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 = ReactiveNotifier<UserState>(() => UserState());
final cartState = ReactiveNotifier<CartState>(() => CartState());
final settingsState = ReactiveNotifier<SettingsState>(() => SettingsState());

// 2. Create relationships correctly
final appState = ReactiveNotifier<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);
        // or use userState, cartState directly, [ Text('Welcome ${userState.name}')]
        
        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 = ReactiveNotifier<CartState>(
  () => CartState(),
  related: [userState] // ❌ Don't do this
);

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

// βœ… CORRECT: Flat structure with single parent
final appState = ReactiveNotifier<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 = ReactiveNotifier<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 #

ReactiveNotifier includes a comprehensive debugging system with detailed error messages:

Creation Tracking #

πŸ“¦ Creating ReactiveNotifier<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 ReactiveNotifier 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 ReactiveNotifier 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

Examples #

Check out our example app for more comprehensive examples and use cases.

Contributing #

We love contributions! Please read our Contributing Guide first.

  1. Fork it
  2. Create your feature branch (git checkout -b feature/amazing)
  3. Commit your changes (git commit -am 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing)
  5. Create a new Pull Request

Support #

  • 🌟 Star the repo to show support
  • πŸ› Create an issue for bugs
  • πŸ’‘ Submit feature requests through issues
  • πŸ“ Contribute to the documentation

License #

This project is licensed under the MIT License - see the LICENSE file for details.


Made with ❀️ by JhonaCodes

2
likes
0
points
317
downloads

Publisher

verified publisherjhonacode.com

Weekly Downloads

2024.07.01 - 2025.01.13

A Dart library for managing reactive state efficiently, supporting multiples related state.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on reactive_notifier