-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Add the createDependency parameter to ModalRoute.of #145389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the createDependency parameter to ModalRoute.of #145389
Conversation
| /// while it is visible (specifically, if [isCurrent] or [canPop] change value). | ||
| @optionalTypeArgs | ||
| static ModalRoute<T>? of<T extends Object?>(BuildContext context) { | ||
| final _ModalScopeStatus? widget = context.dependOnInheritedWidgetOfExactType<_ModalScopeStatus>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found this line of code didn't change in 3.19. but why the action is changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main reason is that these codes were added in the PR #134554
flutter/packages/flutter/lib/src/widgets/routes.dart
Lines 1711 to 1721 in ba39319
| @override | |
| void didChangeNext(Route<dynamic>? nextRoute) { | |
| super.didChangeNext(nextRoute); | |
| changedInternalState(); | |
| } | |
| @override | |
| void didPopNext(Route<dynamic> nextRoute) { | |
| super.didPopNext(nextRoute); | |
| changedInternalState(); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in my scenario ,when calling showDialog will also come across such problem as I said in #145136 (comment) , so this case also need to be dealt;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also applies showDialog
|
|
||
| /// Obtains the element corresponding to the nearest widget of | ||
| /// [_ModalScopeStatus] within the given [context]. | ||
| @visibleForTesting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added @protected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a static method. @protected doesn't make sense here.
| final _ModalScopeStatus? widget = context.dependOnInheritedWidgetOfExactType<_ModalScopeStatus>(); | ||
| static ModalRoute<T>? of<T extends Object?>( | ||
| BuildContext context, { | ||
| bool createDependency = true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What problem is it solving to not create the dependency? In my experience, this kind of API often ends up being a footgun where people forget to switch this to true when their code evolves and they do actually need to rebuild when ModalRoute changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In many cases, people obtain route arguments through ModalRoute.of(context)?.settings.arguments. In this scenario, there is no need to create dependency.
Now after upgrading to 3.19, I found that I obtained the route arguments in Page2 and then pushed to Page3. During the process of Page3 being pushed and popped, the build method of Page2 will be called again because of ModalRoute.of. In this process, it is meaningless for Page2 to re-obtain routing arguments.
2024-03-22.10.08.36.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In many cases, people obtain route arguments through ModalRoute.of(context)?.settings.arguments. In this scenario, there is no need to create dependency.
The settings associated with a route (and with that the arguments) can change, though (see [1]). Not creating a dependency will lead to bugs because widgets that previously read the args will not rebuild with the new args. So, this API will likely be a foot gun. Instead, we could consider an API that only rebuilds when the arguments change. Something like ModalRoute.argumentsOf(context).
[1]
| void _updateSettings(RouteSettings newSettings) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion, but sorry I don’t have time to complete it, thanks for reviewing.
|
@goderbauer Hello, will you continue to review it? If you do not accept the changes in this PR, could you please indicate how to solve unnecessary rebuild caused by use |
|
Yes, I have this on my list of PRs to review and will get back to it shortly. Sorry for the delay. |
|
@goderbauer How does it look? This issue is kinda blocking our update of flutter. |
Have you found any other solution yet? |
@ioma8 We temporarily solve this issue by modifying the flutter source code. # Enter your local flutter directory
cd /Users/lxf/fvm/versions/3.19.3
# Download patch
curl -O https://raw.githubusercontent.com/LinXunFeng/flutter_assets/main/patch/01_rollbak_3_19_routes_change/0001-Roll-back-changes-to-routes.dart.patch
# Apply patch
git apply 0001-Roll-back-changes-to-routes.dart.patchRelated article: Flutter - 升级3.19之后页面多次rebuild?🤨 |
|
This issue is blocking us to upgrade to Flutter 3.19.x |
|
My temporary solution: replace all instances of /// replace ModalRoute.of(context)
class MyModalRoute {
static ModalRoute<dynamic>? of(BuildContext context) {
ModalRoute<dynamic>? route;
context.visitAncestorElements((element) {
if(element.widget.runtimeType.toString() == '_ModalScopeStatus') {
dynamic widget = element.widget;
route = widget.route as ModalRoute;
return false;
}
return true;
});
return route;
}
} |
|
Close when no one care about this issue =)). LOL |
|
真的没人在乎么,我很在乎呀,我这个该死的强迫症 |
It is working for me. Thanks @CoderBuck for the solution. |
According to previous discussion at #145389 (comment), this change makes `_ModalScopeStatus` an `InheritedModel` rather than an `InheritedWidget`, and provides the following methods. - `isCurrentOf` - `canPopOf` - `settingsOf` For example, `ModalRoute.of(context)!.settings` could become `ModalRoute.settingsOf(context)` as a performance optimization.
According to previous discussion at flutter#145389 (comment), this change makes `_ModalScopeStatus` an `InheritedModel` rather than an `InheritedWidget`, and provides the following methods. - `isCurrentOf` - `canPopOf` - `settingsOf` For example, `ModalRoute.of(context)!.settings` could become `ModalRoute.settingsOf(context)` as a performance optimization.
/// replace ModalRoute.of(context)
class MyModalRoute {
static ModalRoute<dynamic>? of(BuildContext context) {
ModalRoute<dynamic>? route;
context.visitAncestorElements((element) {
if(element.widget.runtimeType.toString() == '_ModalScopeStatus') {
dynamic widget = element.widget;
route = widget.route as ModalRoute;
return false;
}
return true;
});
return route;
}
}Is there also a solution when the code is obfuscated? Since the |
Added
createDependencyparameter toModalRoute.of, which allows developer to freely choose to usedependOnInheritedWidgetOfExactTypeorgetElementForInheritedWidgetOfExactTypeto obtainModalRoute.Releated issue:
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.