From 2880ade45c90363197a86ff55f5c17cc8eafbfa1 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 8 Oct 2019 17:06:12 +0100 Subject: [PATCH] Unmount React components before stopping the client This fixes an entire class of React soft crashes that can happen when you: 1. Log out, causing the client peg to become `null` 2. Some async process (event handler, timeout, request, etc.) tries to use the client in a component before it unmounts, triggering a soft crash 3. Several moments later, the app actually unmounts With this change, we change the app's view and unmount components first and then after that we stop the client. Fixes https://github.com/vector-im/riot-web/issues/11078 --- src/Lifecycle.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index a2cfc9a1ba..7490c5d464 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -511,12 +511,7 @@ export function logout() { // logout doesn't work for guest sessions // Also we sometimes want to re-log in a guest session // if we abort the login - - // use settimeout to avoid racing with react unmounting components - // which need a valid matrixclientpeg - setTimeout(()=>{ - onLoggedOut(); - }, 0); + onLoggedOut(); return; } @@ -548,8 +543,11 @@ export function softLogout() { // random clients stopping in the middle of the logs. console.log("Soft logout initiated"); _isLoggingOut = true; // to avoid repeated flags - stopMatrixClient(/*unsetClient=*/false); + // Ensure that we dispatch a view change **before** stopping the client so + // so that React components unmount first. This avoids React soft crashes + // that can occur when components try to use a null client. dis.dispatch({action: 'on_client_not_viable'}); // generic version of on_logged_out + stopMatrixClient(/*unsetClient=*/false); // DO NOT CALL LOGOUT. A soft logout preserves data, logout does not. } @@ -609,9 +607,12 @@ async function startMatrixClient(startSyncing=true) { */ export function onLoggedOut() { _isLoggingOut = false; + // Ensure that we dispatch a view change **before** stopping the client so + // so that React components unmount first. This avoids React soft crashes + // that can occur when components try to use a null client. + dis.dispatch({action: 'on_logged_out'}); stopMatrixClient(); _clearStorage().done(); - dis.dispatch({action: 'on_logged_out'}); } /**