flutter / flutter/samples

[compass_app] UI state never updates for the HomeScreen (regression after the implementation of #2788)

Open
#2,877 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
19.3k
Forks
7.9k
Avg merge
3h 26m
Merged PRs (30d)
3

Description

Serious bug, application doesn't work the inteded way.

(Flutter 3.44.8; platform: Windows; tested on commit 978919b)

Steps to reproduce:
1) Book a new trip;
2) Come back to a home screen;
3) You can't see new trip, unless you hot reload.

Before moving initialization of HomeViewModel into HomeScreenContainer, it relied on rebuild that go_router did:
1) User moves to the home route '/' or deeper;
2) All previous routes including the one where user moved are getting rebuilt, which results in creating new instances of viewModels, which results in them calling _load and fetching latest data from repository.

Now it seems that HomeViewModel is just initialized once in HomeScreenContainer and never updates.

---

Generally according to [this statement](https://github.com/flutter/samples/issues/2604#issuecomment-3164086227), the current way go_router "manages" ui states, is wrong, which already was unfolded in [issue#2574](https://github.com/flutter/samples/issues/2574), but outside of users sharing their ways on how to avoid this behavior, it never really recieved much attention.

So maybe a solution to this bug will also lead to a solution for issue#2574?

I myself temporarly solved issue#2574 in a way where viewModel only updates when user moves directly to a route it was going to. Hopefully this helps:
```
class RouteLifecycleListener extends StatefulWidget {
const RouteLifecycleListener({
required this.onResume,
required this.child,
super.key,
});
final VoidCallback onResume;
final Widget child;

@override
State createState() => _RouteLifecycleListenerState();
}

class _RouteLifecycleListenerState extends State
with RouteAware {
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver.subscribe(this, ModalRoute.of(context)! as PageRoute);
}

@override
void didPopNext() {
widget.onResume();
}

@override
void dispose() {
routeObserver.unsubscribe(this);
super.dispose();
}

@override
Widget build(BuildContext context) {
return widget.child;
}
}
```

```
...
GoRoute(
path: '/home',
name: AppRoute.home.name,
builder: (context, state) => Provider(
create: (context) {
return HomeViewModel(
...
);
},
builder: (context, _) {
return RouteLifecycleListener(
onResume: () => context.read().load.execute(),
child: HomeScreen(viewModel: context.read()),
);
},
),
routes: [ ...
```

Contributor guide

Open the contributing guide

Research direction

Start by tracing HomeViewModel initialization in HomeScreenContainer and the HomeScreen route behavior through go_router, comparing it with the rebuild behavior before #2788. Reproduce the Windows flow by booking a trip and returning home; done means the new trip appears without hot reload and the relevant state update is covered or verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart
Domain
desktop-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.