The answer is actually pretty straightforward and, as usual, the most effective way to understand what's happening behind the scenes is by examining the source code of Ionic.
In summary: the ionViewWillEnter
lifecycle hook is activated before the page transition starts, while the ionViewDidEnter
is triggered after the transition completes. Refer to the end of this response for a link to the relevant source code.
So, when should you utilize each of these hooks? There are various potential scenarios, but here are some suggestions based on my experience with certain applications:
At times, you may need to update information on the page every time the user accesses it; this might involve sending an HTTP request to a remote API to retrieve data. In such cases, using the IonViewWillEnter
could be the suitable choice so that you can initiate the request early, thus fetching the response promptly.
A similar scenario arises when you have to interact with the DOM for specific reasons because the DOM is already loaded when the IonViewWillEnter
is executed. This approach can help in initializing the page quickly, potentially presenting it to the user ready for use.
Similarly, if you need to initialize the view with parameters obtained from the preceding view, opting for the ionViewWillEnter
lifecycle hook would suffice for this uncomplicated task, enabling the view to be displayed already initialized to the user.
When should you then employ the ionViewDidEnter
?
On occasions where running the app on older android devices with limited RAM causes slight lag during animations initiated in the ionViewWillEnter
, it might be preferable to make API requests in the ionViewDidEnter
to ensure completion of the animation.
In certain applications, incorporating intricate animations into elements of the pushed page—such as bringing content from below, fading elements after a delay, and more—is required. Utilizing Angular animations (to manage timing) and employing the ionViewDidEnter
hook can ensure smooth execution of these animations. Consequently, users perceive the element animations within the page as a seamless continuation of the overall page transition.
To examine the NavControllerBase code:
1) IonViewWillEnter
// around line 666...
_transitionStart(...): Promise<NavResult> {
// ...
// around line 700...
// create a callback that needs to run within zone
// that will fire off the willEnter/Leave lifecycle events at the right time
transition.beforeAddRead(this._viewsWillLifecycles.bind(this, enteringView, leavingView));
// ...
}
Further...
// around line 805...
_viewsWillLifecycles(enteringView: ViewController, leavingView: ViewController) {
if (enteringView || leavingView) {
this._zone.run(() => {
// Here, the order is important. WillLeave must be called before WillEnter.
leavingView && this._willLeave(leavingView, !enteringView);
enteringView && this._willEnter(enteringView);
});
}
}
Reviewing the definition of beforeAddRead
in the animation.d.ts
reveals:
/**
* Add a function which contains DOM reads, which will run
* before the animation begins.
*/
beforeAddRead(domReadFn: Function): Animation;
Hence, we can confirm that the ionViewWillEnter
lifecycle hook executes prior to the page transition onset
2) IonViewDidEnter
This one is relatively straightforward. Once again, referring to the same NavControllerBase
:
// around line 743...
_transitionFinish(...): NavResult {
// ...
// around line 753...
if (hasCompleted) {
// transition has completed (went from 0 to 1)
if (enteringView) {
enteringName = enteringView.name;
this._didEnter(enteringView);
}
// ..
}
// ...
}
And
// around line 939...
_didEnter(view: ViewController) {
assert(this.isTransitioning(), 'nav controller should be transitioning');
assert(NgZone.isInAngularZone(), 'callback should be zoned');
try {
view._didEnter();
this.viewDidEnter.emit(view);
this._app.viewDidEnter.emit(view);
} catch (e) {
this._errHandler && this._errHandler.handleError(e);
}
}
Consequently, we determine that the ionViewDidEnter
lifecycle hook is activated following completion of the transition.