microstate 1.0.1 copy "microstate: ^1.0.1" to clipboard
microstate: ^1.0.1 copied to clipboard

A lightweight, reactive state management solution for Flutter applications with built-in history tracking, validation, debouncing, and throttling capabilities.

microstate #

A lightweight, reactive state management solution for Flutter applications. Microstate provides a simple and intuitive API for managing state with built-in history tracking, validation, debouncing, and throttling capabilities.

Features #

  • ๐ŸŽฏ Simple API - Easy to use with minimal boilerplate
  • ๐Ÿ”„ Reactive - Automatic UI updates when state changes
  • ๐Ÿ“š History Tracking - Built-in undo/redo functionality
  • โœ… Validation - Optional value validation
  • โฑ๏ธ Debouncing & Throttling - Control update frequency
  • ๐ŸŽจ Widget Integration - Seamless integration with Flutter widgets
  • ๐Ÿงช Type Safe - Full type safety with generics
  • ๐Ÿš€ Lightweight - Minimal overhead and dependencies
  • ๐ŸŒ Context-Independent - No BuildContext required, no "called before build" errors

Why Microstate? #

Context-Independent Design #

Unlike many other state management solutions, microstate is completely context-independent. This means:

  • โœ… No BuildContext required - State can be created anywhere
  • โœ… No widget tree dependency - Works independently of widget hierarchy
  • โœ… No initialization order issues - No "state being called before build has executed" errors
  • โœ… Flexible placement - Can be created in constructors, initState, or even as global variables
  • โœ… Simple testing - Easy to test without widget context
// โœ… Works perfectly - no context needed
final counter = state(0);

// โœ… Safe to call in initState
@override
void initState() {
  super.initState();
  counter = state(0); // No errors!
}

// โœ… Can be created anywhere
class MyService {
  final userState = state<User?>(null);
  final settingsState = state<Settings>(Settings.defaults());
}

Installation #

Add microstate to your pubspec.yaml:

dependencies:
  microstate: ^1.0.0

Then run:

flutter pub get

Quick Start #

Basic Usage #

import 'package:flutter/material.dart';
import 'package:microstate/microstate.dart';

class CounterPage extends StatefulWidget {
  const CounterPage({super.key});

  @override
  State<CounterPage> createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  late final ValueState<int> counter;

  @override
  void initState() {
    super.initState();
    counter = state(0);
  }

  @override
  void dispose() {
    counter.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // Reactive counter display
            Observer(
              state: counter,
              builder: (context, value) => Text(
                'Count: $value',
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ),
            const SizedBox(height: 20),
            
            // Action buttons
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () => counter.decrement(),
                  child: const Text('Decrement'),
                ),
                const SizedBox(width: 16),
                ElevatedButton(
                  onPressed: () => counter.increment(),
                  child: const Text('Increment'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

API Reference #

Creating State #

Basic State

// Create a simple state
final counter = state(0);

// Access the current value
print(counter.value); // 0

// Update the value
counter.value = 5;

State with History

// Create state with history tracking (default: 10 items)
final counter = stateWithHistory(0, maxHistorySize: 5);

counter.value = 1;
counter.value = 2;
counter.value = 3;

// Undo to previous value
counter.undo(); // Now value is 2

// Check if undo is available
if (counter.canUndo) {
  counter.undo();
}

// Get history
print(counter.history); // [0, 1, 2]

State with Validation

// Create state with validation
final age = stateWithValidation(0, validator: (value) => value >= 0 ? value : 0);

age.value = -5; // Will be validated to 0
age.value = 25; // Will be set to 25

Updating State #

Direct Updates

final counter = state(0);
counter.value = 10;

Transform Updates

final counter = state(0);

// Update using a transformation function
counter.update((value) => value + 1);

// Async updates
final user = stateAsync<User?>(null);
await user.updateAsync((current) async => await fetchUser());

Debounced Updates

final searchQuery = state('');

// Only the last update within 300ms will be applied
searchQuery.debouncedUpdate(
  (value) => value + 'a',
  Duration(milliseconds: 300),
);

Throttled Updates

final scrollPosition = state(0.0);

// Updates are limited to once per 100ms
scrollPosition.throttledUpdate(
  (value) => newPosition,
  Duration(milliseconds: 100),
);

Widget Integration #

Observer Widget

Observer(
  state: counter,
  builder: (context, value) => Text('Count: $value'),
)

Manual Listeners

final counter = state(0);

counter.addListener(() {
  print('Counter changed to: ${counter.value}');
});

counter.value = 5; // Triggers the listener

Extension Methods #

Numeric Operations

final counter = state(0);

counter.increment(); // value becomes 1
counter.decrement(); // value becomes 0

Boolean Operations

final isEnabled = state(false);

isEnabled.toggle(); // value becomes true
isEnabled.toggle(); // value becomes false

Examples #

Form State Management #

class FormState {
  final name = state('');
  final email = state('');
  final age = stateWithValidation(0, validator: (value) => value >= 0 ? value : 0);
  final isSubmitting = state(false);

  bool get isValid => name.value.isNotEmpty && email.value.contains('@') && age.value > 0;

  Future<void> submit() async {
    isSubmitting.value = true;
    try {
      await submitForm();
    } finally {
      isSubmitting.value = false;
    }
  }
}

Search with Debouncing #

class SearchPage extends StatefulWidget {
  @override
  State<SearchPage> createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  late final ValueState<String> searchQuery;
  late final ValueState<List<Item>> searchResults;

  @override
  void initState() {
    super.initState();
    searchQuery = state('');
    searchResults = state([]);
  }

  void onSearchChanged(String query) {
    searchQuery.debouncedUpdate(
      (value) => query,
      Duration(milliseconds: 300),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          onChanged: onSearchChanged,
          decoration: InputDecoration(labelText: 'Search'),
        ),
        Observer(
          state: searchResults,
          builder: (context, results) => ListView.builder(
            itemCount: results.length,
            itemBuilder: (context, index) => ListTile(
              title: Text(results[index].title),
            ),
          ),
        ),
      ],
    );
  }
}

Best Practices #

  1. Always dispose of state when you're done with it to prevent memory leaks
  2. Use appropriate state types - state() for simple values, stateWithHistory() for undoable state, stateWithValidation() for validated state
  3. Leverage debouncing for search inputs and other frequent updates
  4. Use throttling for scroll events and other high-frequency updates
  5. Combine with Observer widget for automatic UI updates

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

License #

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

4
likes
160
points
30
downloads

Publisher

verified publisherflutteroiditservices.in

Weekly Downloads

A lightweight, reactive state management solution for Flutter applications with built-in history tracking, validation, debouncing, and throttling capabilities.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on microstate