Halte den State im gemeinsamen Vorfahren und mach aus deinen Kind-Widgets kontrollierte Widgets, die Änderungen über Callbacks zurückmelden.
Diese Lektion in Kodokon öffnenEine klassische Situation: Ein Mengenwähler und eine an anderer Stelle angezeigte Summe müssen dieselben Daten teilen. Die goldene Regel: Der State lebt im nächstgelegenen gemeinsamen Vorfahren der Widgets, die von ihm abhängen. Das Eltern-Widget besitzt die Daten, reicht sie als Parameter nach unten und erhält Änderungen über einen Callback, der nach oben zurückfließt. Das ist "lifting state up".
import 'package:flutter/material.dart';
class CartScreen extends StatefulWidget {
const CartScreen({super.key});
@override
State<CartScreen> createState() => _CartScreenState();
}
class _CartScreenState extends State<CartScreen> {
int _quantity = 1;
void _updateQuantity(int value) {
setState(() => _quantity = value);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Cart')),
body: Column(
children: [
QuantitySelector(
quantity: _quantity,
onChanged: _updateQuantity,
),
Text('Total: ${_quantity * 20} €'),
],
),
);
}
}Das Kind wird zu einem kontrollierten Widget: Es ist ein StatelessWidget, speichert nichts, zeigt den Wert an, den es erhält, und signalisiert jede Absicht über onChanged. ValueChanged<int> ist einfach ein Alias für void Function(int). Beachte den Minus-Button, der bei Menge 1 deaktiviert ist: null an onPressed zu übergeben genügt, und diese Logik ergibt sich direkt aus dem erhaltenen Wert.
import 'package:flutter/material.dart';
class QuantitySelector extends StatelessWidget {
const QuantitySelector({
super.key,
required this.quantity,
required this.onChanged,
});
final int quantity;
final ValueChanged<int> onChanged;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: const Icon(Icons.remove),
onPressed: quantity > 1
? () => onChanged(quantity - 1)
: null,
),
Text('$quantity'),
IconButton(
icon: const Icon(Icons.add),
onPressed: () => onChanged(quantity + 1),
),
],
);
}
}Du nutzt diesen Vertrag ständig, ohne es zu merken: Checkbox, Slider und Switch sind alle kontrollierte Widgets (value + onChanged). Wenn der Baum tiefer wird und es mühsam wird, Callbacks durch fünf Ebenen zu fädeln, ist es Zeit, Lösungen für State-Management zu entdecken - das ist das Thema des nächsten Moduls.