惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
雷峰网
雷峰网
Last Week in AI
Last Week in AI
T
Tailwind CSS Blog
V
Visual Studio Blog
Jina AI
Jina AI
博客园 - 司徒正美
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
小众软件
小众软件
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
IT之家
IT之家
WordPress大学
WordPress大学
爱范儿
爱范儿
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
🚀 Which Flutter State Management Should You Use? (Complet...
Codexlancers · 2026-04-29 · via DEV Community

Flutter makes building beautiful apps easy — but as your app grows, managing data across screens becomes challenging.

You may have faced issues like:

UI not updating properly
Data not syncing between screens
Too many unnecessary rebuilds
👉 This is exactly where state management becomes essential.

In this guide, we’ll break down everything — from basics to advanced approaches — so you can confidently choose the right solution.

🧠** What is State Management?**
In simple terms:

👉 State = Any data that changes in your app

Examples:

Counter value
API response
User login status
Theme (dark/light)
👉 State Management = How you manage and update that data efficiently across your app

Without proper state management:

Your UI becomes unpredictable
Code becomes hard to maintain
Scaling becomes difficult
🔰 1. setState (The Simplest Way)
🧾 What it is
Built-in Flutter method to update UI when state changes.

📦 Example :

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

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

class _CounterPageState extends State<CounterPage> {
  int _count = 0;

  void _increment() {
    setState(() {         // triggers a rebuild
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text('Count: $_count')),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

✅ When to use :
Purely local UI interactions with no cross-widget communication — toggle buttons, form field validation, simple animations, local loading spinners.

🌱 2. Provider
🧾 What it is
A wrapper around InheritedWidget for structured state management.

📦 Example :

// 1. Define a ChangeNotifier
class CartProvider extends ChangeNotifier {
  final List<String> _items = [];
  List<String> get items => _items;

  void addItem(String item) {
    _items.add(item);
    notifyListeners(); // triggers rebuild in listeners
  }
}

// 2. Wrap your tree with ChangeNotifierProvider
ChangeNotifierProvider(
  create: (_) => CartProvider(),
  child: const MyApp(),
)

// 3. Read or watch in any descendant widget
final cart = context.watch<CartProvider>();
Text('${cart.items.length} items in cart')

Enter fullscreen mode Exit fullscreen mode

When to use :
Small-to-medium apps with straightforward state that doesn’t need complex async logic. Great for your first real Flutter project beyond tutorials.

3. Riverpod (Modern Approach)
🧾 What it is
A more powerful and safer version of Provider.

📦 Example :

// pubspec.yaml
// riverpod_annotation: ^4.0.2
// riverpod_generator: ^4.0.3

part 'auth_notifier.g.dart';

// Class-based notifier with codegen
@riverpod
class AuthNotifier extends _$AuthNotifier {
  @override
  AuthState build() => const AuthState.initial();

  Future<void> signIn(String email, String password) async {
    state = const AuthState.loading();
    try {
      final user = await AuthService().signIn(email, password);
      state = AuthState.authenticated(user);
    } catch (e) {
      state = AuthState.error(e.toString());
    }
  }
}

// In a ConsumerWidget — no BuildContext magic needed
class AuthScreen extends ConsumerWidget {
  const AuthScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final authState = ref.watch(authNotifierProvider);

    return authState.when(
      initial: () => const LoginScreen(),
      loading: () => const CircularProgressIndicator(),
      authenticated: (user) => HomeScreen(user: user),
      error: (msg) => ErrorView(message: msg),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

When to use :
Medium-to-large apps where you want clean architecture, excellent async support, and testability without Bloc’s ceremony. Excellent choice for solo developers and small teams building production apps.

🧱** 4. Bloc / Cubit (Enterprise-Level)**
🧾 What it is
A structured pattern using streams.

Bloc → Event-driven
Cubit → Simpler version
📦 Example :

// State class
class AuthState {
  final bool isAuthenticated;
  final String? userId;
  const AuthState({required this.isAuthenticated, this.userId});
}

// Cubit — logic lives here, NOT in the widget
class AuthCubit extends Cubit<AuthState> {
  AuthCubit() : super(const AuthState(isAuthenticated: false));

  Future<void> signIn(String email, String password) async {
    final user = await AuthService.signIn(email, password);
    emit(AuthState(isAuthenticated: true, userId: user.id));
  }

  void signOut() => emit(const AuthState(isAuthenticated: false));
}

// Widget — just listens, zero logic
BlocBuilder<AuthCubit, AuthState>(
  builder: (context, state) {
    return state.isAuthenticated
        ? const HomeScreen()
        : const LoginScreen();
  },
)

Enter fullscreen mode Exit fullscreen mode

When to use :
Large-scale apps with complex business logic, multiple async operations, strict testability requirements, or teams that need predictable, traceable state transitions. Common in enterprise and fintech Flutter apps.

5. GetX (Fast & Lightweight)
🧾 What it is
All-in-one solution (state + routing + dependency injection).


📦 Example :

// Controller — reactive variables with .obs
class ProfileController extends GetxController {
  final RxString name = ''.obs;
  final RxBool isLoading = false.obs;

  Future<void> loadProfile() async {
    isLoading.value = true;
    final data = await ApiService().getProfile();
    name.value = data.name;
    isLoading.value = false;
  }
}

// Widget — Obx auto-rebuilds when .obs changes
class ProfilePage extends GetView<ProfileController> {
  @override
  Widget build(BuildContext context) {
    return Obx(() {
      if (controller.isLoading.value) {
        return const CircularProgressIndicator();
      }
      return Text(controller.name.value);
    });
  }
}

// Navigation — no BuildContext needed
Get.to(() => const ProfilePage());
Get.back();

Enter fullscreen mode Exit fullscreen mode

When to use :
Prototypes, hackathons, small personal projects, or when you need to move very fast and want everything under one roof. Use with caution in large team environments.

🧩 Real-World Use Cases
🟢 Small Apps
Use:

  • setState
  • Provider 👉 Example: Forms, basic apps

🟡 Medium Apps
Use:

  • Provider
  • GetX 👉 Example: Dashboard, e-commerce

🔵 Large Apps
Use:

  • Riverpod
  • Bloc 👉 Example: Production apps with APIs

🔴 Team / Enterprise
Use:

  • Bloc
  • Riverpod 👉 Better maintainability and structure

🏁** Final Recommendation**
👶 Beginner
Start with:

  • setState → then Provider
    🧑‍💻 Intermediate
    Use:

  • Riverpod (recommended)

  • or GetX
    🧠 Advanced / Production
    Use:

  • Riverpod (modern + scalable)

  • Bloc (enterprise structure)

💡 Final Thoughts
There is no single “best” state management solution.

👉 The right choice depends on:

  • App complexity

  • Team size

  • Development speed

  • Maintainability needs