Why does Hot Reload sometimes not take into account my change?
The Flutter.io Using Hot Reload page says “ if the modified code won’t be re-executed as a result of rebuilding the widget tree, then you won’t see its effects after hot reload.”
The topic has been discussed in issues #13831 and #18709, the problem being that Hot Reload does not work on dialogs. In the first issue Ian Hickson gives the explanation and the solution to make it work. In the second, Thomas Burkhart provides an example of the solution.
After spending some time trying to understand the problem and the solution, I considered it would be useful to put it here as a reference for the future.
Look at the following code:
This shows a dialog when you press the button. If you change the button text, “Click here”, and do a hot reload, the text is updated.
But, if you change the text in the title or content of the dialog, those strings are not updated on the screen.
Why? As Ian Hickson says, it’s because the code in the onPressed: property is not re-run. Even if MyHome widget is rebuilt. Since the code is not re-run the AlertDialog constructor is not called and the strings are not updated.
The solution is to create a custom widget. Consider the following snippet with the new CustomAlertWidget:
If you now change the text in the inner AlertDialog constructor, say content: Text(“New content”), Hot Reload does effectively update the screen with the new screen.
What’s the difference?
Ian says in issue #13831: “(hot reload) just updates code that would normally run, then marks everything dirty.”
- In the first case, you are modifying a constructor call, but the constructor is not run until you tap again.
- In the second case, you are also modifying a constructor but it is inside the normal flow of exectuion of the build method so the AlertDialog is recreated when the build() method is run.
You might still be saying: The AlertDialog in the first case has also a build() method like the custom one, why the difference?
Again, the secret is where in the tree you make the change and if the part of the code where you make the change is re-executed as a result of a re-build.
What if you change the AlertDialog build() method itself?
Try the following (remember to undo the change later on).
child: new Semantics(child: “New title”, namesRoute: true)
Do a Hot Reload. Was the text in the dialog updated? Yes!!
By modifying the text on that build() method, you end up having the same result in both cases.
Just play around with both snippets and you will quickly grasp the concept.
I have later faced this issue when trying to provide an answer in StackOverflow. In this SO question you can find a real application of this post. Calling `setState()` in the main page did not call a rebuild of the dialog.