defect
major
#29446
React: Zustand einer Seite über einen Reload hinweg erhalten
Selektiert man in einer React-Tabelle eine Zeile und lädt die Seite neu (F5), ist die Selektion verloren. Dasselbe gilt für alles andere, was die Seite an Zustand hält: Scrollposition und Aufklappzustand einer Tabelle, Eingaben in einem Formular, die Seite eines Pagers.
Ursache
Die React-View-Schicht baute bei jedem GET den gesamten serverseitigen Control-Baum neu auf. Der Zustand lag ausschließlich in diesem Baum; erhalten blieben nur SubSession, Update-Queue und PersonalConfiguration. Verstärkt wurde das dadurch, dass der Client beim Entladen der Seite windowClosed meldet — beforeunload feuert bei einem Reload genauso wie beim Schließen —, woraufhin der Server den kompletten Fenster-Zustand abbaute.
Lösung
- Ein Reload wird vom Schließen unterschieden: die Selbstmeldung beim Entladen hält das Fenster für eine Karenzzeit vor, statt es abzubauen. Ein Fenster, das nicht zurückkommt, wird von der nächsten Anfrage derselben Session eingesammelt.
- Ein Reload rendert den Baum, den das Fenster noch hält, statt einen neuen zu bauen. Wiederverwendet wird nur bei gleicher View; ein Login verwirft alles.
- Fenster-Zustand (Queue, Model-Scope, Baum) liegt jetzt gemeinsam im WindowEntry.
- Ein Control hängt sich beim Rendern selbst an, und die Weitergabe von Attach und Detach leitet sich aus den Kindern im State ab. Damit ist der Anzeige-Zustand erstmals verlässlich — vorher wurde unterhalb von neun Containern, die die Weitergabe nicht implementierten, nie abgemeldet. Modell-Observer und Command-Models hängen seither am Attach statt am Rendern; die frühere addBeforeWriteAction entfällt.
- Ebenso leitet sich das Wegräumen aus dem State ab, abzüglich der Kinder, die ein Control nur zum Rendern geliehen bekommt (<slot>-Platzhalter). Von 33 Aufzählungen je Container bleiben 8 — die Cache-Halter, die auch das gerade nicht Angezeigte wegräumen müssen. Dabei kam heraus, dass FormControl seine Kinder nie wegräumte; das ist behoben.