ryer.io

Bug 2732: Nav Components Vanishing on Logout

TL;DR

  • Navigation components disappeared on logout, and behaved unpredictably on cancel.
  • userPrograms went undefined while userRoles stayed intact — two pieces of user state diverging.
  • Cause: the logout action clears user data when logout starts, not when it succeeds.
  • Keying the change on wasLogoutSuccessful fixed it, including the cancelled-logout case.
  • A separate “Device storage not initialized” error survived every change, which means I had the wrong component.

Bug 2732: logging out from the nav screen makes key components disappear. Reproducing it takes ten seconds — go to the nav screen, hit logout, watch several components vanish — which at least made this pleasant to investigate.

Narrowing it down

My first instinct was the authentication context and the sign-out logic, on the theory that the logout action was affecting render somewhere.

I instrumented the app menu, targeting “My Vision” since that’s the button that reliably disappears. It goes on logout. Others behave unpredictably when you hit cancel — and that’s the more telling case, because a cancelled logout shouldn’t change anything at all.

Tracing the state: clicking logout sets isLoggingOut to true. The app menu’s visibility logic depends on it, and the useEffect keyed off it triggers re-renders that don’t look necessary.

But isLoggingOut turned out to be the messenger rather than the culprit. The values that actually decide what renders are auth.userRoles and user.programs, so I logged both. userPrograms went undefined on logout while userRoles stayed intact.

Two pieces of user state behaving differently is a strong signal. It pointed away from the nav components entirely and at how the logout state is managed.

The cause

In the appData context, the logout action returns an initial user state and fires as soon as the logout process begins. So the code clears user data on the attempt, not on the result.

That explains both symptoms at once. Log out and the data is gone, which is fine. Cancel a logout and the data is already gone, which is the bug — the state was destroyed before anyone knew whether the user meant it.

The fix

Rather than clearing during logout, I keyed the state change on wasLogoutSuccessful. Navigation now stays stable through a cancelled logout, which was the actual broken behaviour. I reverted the non-essential dependency shuffling I’d done while hunting and kept just this.

What I didn’t fix

A “Device storage not initialized” cache error persisted throughout. I looked for a race condition between transitions and found none. Stripping dependencies didn’t move it either.

That last part is the useful signal rather than a dead end: if removing the dependencies changes nothing, my assumption about which component is failing is simply wrong. It lives somewhere I haven’t examined yet.

Worth noting the conditions — a little guy was demanding attention throughout. Staying iterative rather than thrashing is most of the skill on days like that.