Lightning navigation does not refresh the state of components, how to fix a bug

We're running into this too. We expected it to be the case that if we navigate to a Lightning Component URL once, then walk through other pages, then navigate back to it with a different URL, we'll get a brand new instance and see the init method fire. Instead we get a stale older version with no init fired. So it's not clear what to do if what we really want is that new instance.

Will post back here if we find out exactly the best way to work around it.

EDIT: Aha! I found a relevant approach.

In the component with lightning:isUrlAddressable simply add a change handler for the pageReference state.

<aura:handler name="change" value="{!v.pageReference}" action="{!c.reInit}" />

And then your reInit method can reset the component back to whatever it needs to be. If you need more fine-grained logic (only reset it if a specific parameter changed, etc) then your reInit method can compare values as needed to produce the desired logic.

As far as I can tell in brief testing, the change handler does not fire on initial load (use your usual init method for that), nor on being reached via back/forward button. It fires on re-navigation to the component (even if the state parameters passed are identical) and it fires if the component internally uses lightning:navigation to change its own state.


I found a relevant approach.

In the component with lightning:isUrlAddressable simply add a change handler for the pageReference state.

Component:

<aura:handler name="change" value="{!v.pageReference}" action="{!c.reInit}" />

Controller.js:

    reInit : function(component, event, helper) {
        $A.get('e.force:refreshView').fire();
    }

I have the same issue with you, aura init event is not getting fired when second time visits the same lightning component.

My workaround is firing the refresh event after navigating to the Lightning component.

navigateToMyCmp : function(component, event, helper) {
    event.preventDefault();
    var pageReference = {
        type: 'standard__component',
        attributes: {
            componentName: 'c__MyCmp',
        },
        state: {
            "recordId": component.get("v.recordId")
        }
    };
    helper.navService(component, pageReference);
    helper.delayedRefresh();
}, 

navService : function(component, pageReference, replace){
    let _replace = replace || false;
    let navService  = component.getSuper().find('navigationService');
    navService.navigate(pageReference, _replace);

},

delayedRefresh : function(milliseconds){
    let ms = milliseconds || 500;
    window.setTimeout($A.getCallback(function(){
        $A.get('e.force:refreshView').fire();
    }),ms);
},