setState is fine for one widget, but shared/app-wide state needs a state-management solution. Popular choices: Provider and Riverpod.
Provider example
class CartModel extends ChangeNotifier {
final List<Item> items = [];
void add(Item i) { items.add(i); notifyListeners(); }
}
// provide it near the top
ChangeNotifierProvider(create: (_) => CartModel(), child: MyApp());
// read/watch it
final cart = context.watch<CartModel>();
Text('${cart.items.length} items');
notifyListeners() rebuilds widgets that are watching the model.
Tip: Start with Provider (simple and official). Riverpod is a more powerful, compile-safe evolution worth learning next.
Summary
Use setState for local UI; use Provider/Riverpod with ChangeNotifier + notifyListeners for shared app state.