From 965959c964348bbbed6013fa70b4bce52da58f57 Mon Sep 17 00:00:00 2001 From: Rish Date: Wed, 23 Sep 2020 20:37:59 +0530 Subject: [PATCH] Cleared timeouts in App on unmount no issue - Clears any timeout on unmount in main App and components to avoid unexpected unmount behaviors --- ghost/portal/src/App.js | 14 ++++++++++---- ghost/portal/src/App.test.js | 2 +- ghost/portal/src/components/Notification.js | 6 +++++- .../portal/src/components/pages/AccountPlanPage.js | 6 +++++- ghost/portal/src/components/pages/SignupPage.js | 8 ++++++-- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/ghost/portal/src/App.js b/ghost/portal/src/App.js index 2f09bfabec..f581cea6ba 100644 --- a/ghost/portal/src/App.js +++ b/ghost/portal/src/App.js @@ -19,8 +19,11 @@ const DEV_MODE_DATA = { export default class App extends React.Component { constructor(props) { super(props); - // Setup custom trigger button handling - this.setupCustomTriggerButton(); + + if (!props.testState) { + // Setup custom trigger button handling + this.setupCustomTriggerButton(); + } // testState is used by App.test to pass custom default state for testing this.state = props.testState || { @@ -35,7 +38,9 @@ export default class App extends React.Component { } componentDidMount() { - this.initSetup(); + if (!this.props.testState) { + this.initSetup(); + } } componentDidUpdate(prevProps, prevState) { @@ -45,7 +50,8 @@ export default class App extends React.Component { } componentWillUnmount() { - this.customTriggerButtons.forEach((customTriggerButton) => { + clearTimeout(this.timeoutId); + this.customTriggerButtons && this.customTriggerButtons.forEach((customTriggerButton) => { customTriggerButton.removeEventListener('click', this.clickHandler); }); } diff --git a/ghost/portal/src/App.test.js b/ghost/portal/src/App.test.js index 996cea242a..35f4fcb59b 100644 --- a/ghost/portal/src/App.test.js +++ b/ghost/portal/src/App.test.js @@ -6,7 +6,7 @@ import App from './App'; const setup = (overrides) => { const testState = { site, - member: member.free, + member: null, action: 'init:success', brandColor: site.accent_color, page: 'signup', diff --git a/ghost/portal/src/components/Notification.js b/ghost/portal/src/components/Notification.js index 774fc8e9c2..f82fe8c1a8 100644 --- a/ghost/portal/src/components/Notification.js +++ b/ghost/portal/src/components/Notification.js @@ -76,6 +76,10 @@ class NotificationContent extends React.Component { }; } + componentWillUnmount() { + clearTimeout(this.timeoutId); + } + onNotificationClose() { this.props.onHideNotification(); } @@ -97,7 +101,7 @@ class NotificationContent extends React.Component { className: 'slideout' }); } else if (autoHide) { - setTimeout(() => { + this.timeoutId = setTimeout(() => { this.setState({ className: 'slideout' }); diff --git a/ghost/portal/src/components/pages/AccountPlanPage.js b/ghost/portal/src/components/pages/AccountPlanPage.js index d4d634bde9..384070e19d 100644 --- a/ghost/portal/src/components/pages/AccountPlanPage.js +++ b/ghost/portal/src/components/pages/AccountPlanPage.js @@ -251,6 +251,10 @@ export default class AccountPlanPage extends React.Component { this.state = this.getInitialState(); } + componentWillUnmount() { + clearTimeout(this.timeoutId); + } + getInitialState() { const {member, site} = this.context; this.plans = getSitePlans({site, includeFree: false}); @@ -309,7 +313,7 @@ export default class AccountPlanPage extends React.Component { // Work as checkboxes for free member plan selection and button for paid members if (!isPaidMember({member})) { // Hack: React checkbox gets out of sync with dom state with instant update - setTimeout(() => { + this.timeoutId = setTimeout(() => { this.setState((state) => { return { selectedPlan: name diff --git a/ghost/portal/src/components/pages/SignupPage.js b/ghost/portal/src/components/pages/SignupPage.js index 97bd576d66..4f478b5954 100644 --- a/ghost/portal/src/components/pages/SignupPage.js +++ b/ghost/portal/src/components/pages/SignupPage.js @@ -148,6 +148,10 @@ class SignupPage extends React.Component { } } + componentWillUnmount() { + clearTimeout(this.timeoutId); + } + handleSignup(e) { e.preventDefault(); this.setState((state) => { @@ -190,7 +194,7 @@ class SignupPage extends React.Component { handleSelectPlan(e, name) { e.preventDefault(); // Hack: React checkbox gets out of sync with dom state with instant update - setTimeout(() => { + this.timeoutId = setTimeout(() => { this.setState((prevState) => { return { plan: name @@ -414,7 +418,7 @@ class SignupPage extends React.Component { sectionClass = 'singleplan'; } } - + return ( <>