diff --git a/chapters/basics/state-management.tex b/chapters/basics/state-management.tex index 1d6afa5..2164da7 100644 --- a/chapters/basics/state-management.tex +++ b/chapters/basics/state-management.tex @@ -44,4 +44,35 @@ Anschaulich lässt sich dies durch das Beispiel \autoref{fig:flutterTreeSetState  \subsubsection{InheritedWidget} -Neben der Möglichkeit, den Zustand über den Widget-Baum nach unten weiter zu propagieren, bietet Flutter noch das Konzept \texttt{InheritedWidget} an. Diese Widgets bilden eine eigene Widget-Gruppe und sind weder den \texttt{StatefulWidgets} noch den \texttt{StatelessWidgets} zuzuordnen. \ No newline at end of file +Neben der Möglichkeit, den Zustand über den Widget-Baum nach unten weiter zu propagieren, bietet Flutter noch das Konzept \texttt{InheritedWidget} an. Diese Widgets bilden eine eigene Widget-Gruppe und sind weder den \texttt{StatefulWidgets} noch den \texttt{StatelessWidgets} zuzuordnen. \autocite[Kap.8.2.1]{flutterinaction} \texttt{InheritedWidgets} ermöglichen es nachgeordneten Widgets, auf den Zustand des Widgets direkt zuzugreifen. Hier muss allerdings beachtet werden, dass das \texttt{InheritedWidget} immer unveränderlich ist. Dies bedeutet, dass andere Widgets über die Veränderung von Konstruktor-Parametern neue Instanzen des Widgets erstellen müssen, um eine Zustandsänderung zu bewirken. Daher lassen sich diese Widgets oft in Kombination mit \texttt{StatefulWidgets}, welche für die Manipulation des Zustands zuständig sind, vorfinden. + +Im Beispiel \autoref{lst:inheritedWidgetExample} kann man erkennen, dass das Widget lediglich die Daten lagert, welche zur Verfügung gestellt werden sollen. In diesem Fall ist dies der aktuelle Benutzende \texttt{currentUser}. Diese*r kann nicht vom \texttt{InheritedWidget} selbst geändert werden, sondern hängt von der Eingabe im Konstruktor ab. Das \texttt{InheritedWidget} wird dabei gemäß des Mottos \blockquote{Everything is a widget} in dem Widget-Baum integriert. Der Konstruktor-Parameter \texttt{child} gibt dabei das im Baum untergeordnete Widget an. Über die \texttt{updateShouldNotify}-Methode wird dem Framework kommuniziert, ob sich der Zustand im vergleich zum vorherigen geändert hat, und somit ein Neubauen der Widgets, die dieses \texttt{InheritedWidget} referenzieren, notwendig ist. + +\begin{lstlisting}[caption={Aufbau eines InheritedWidget}, label={lst:inheritedWidgetExample}] +import 'package:flutter/widgets.dart'; + +class UserStore extends InheritedWidget { + const UserStore({ + Key? key, + required this.currentUser, + required Widget child, + }) : super(key: key, child: child); + + final User currentUser; + + static UserStore? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } + + @override + bool updateShouldNotify(UserStore old) { + return currentUser != old.currentUser; + } +} +\end{lstlisting} + +Anders als bei dem \texttt{setState}-Konzept kann hier direkt der Zustand durch andere nachgelagerte Widgets referenziert werden. Dafür werden oft Hilfsmethoden wie in diesem Fall die \texttt{of}-Methode verwendet. Diese greifen auf Werkzeuge des Frameworks zu, die das \texttt{InheritedWidget} des angebenden Typen zurückgibt und sicherstellt, dass bei einer Veränderung des \texttt{InheritedWidget} das referenzierende Widget auch neugebaut wird und so die Änderung beachtet wird. + +Dieser Mechanismus wird auch von diversen anderen Zustandsverwaltungssystemen verwendet. + +\subsubsection{BLoC} \ No newline at end of file