From e9309880d18cf03c1c139b00fe4b80794804e3de Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Tue, 9 May 2023 17:29:04 -0400 Subject: [PATCH] fix(content): prevent forceUpdate in SSR (#27440) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue number: Resolves #27411, https://github.com/ionic-team/stencil/issues/2429, https://github.com/ionic-team/stencil/issues/4076 --------- ## What is the current behavior? Rendering `` in an Angular Universal project will result in a javascript heap exception and the browser tab timing out. `forceUpdate` is not a compatible API with pre-rendering and results in calling itself indefinitely. ## What is the new behavior? - Updates the fullscreen implementation of `ion-content` to only call `forceUpdate` and related functionality when running in a browser environment. - `` is compatible with Angular Universal ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev-build: `7.0.6-dev.11683653232.1ddc5840` ✅ --- core/src/components/content/content.tsx | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/core/src/components/content/content.tsx b/core/src/components/content/content.tsx index b0d6ca1161b..5a1e2085636 100644 --- a/core/src/components/content/content.tsx +++ b/core/src/components/content/content.tsx @@ -1,5 +1,5 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; -import { Component, Element, Event, Host, Listen, Method, Prop, forceUpdate, h, readTask } from '@stencil/core'; +import { Build, Component, Element, Event, Host, Listen, Method, Prop, forceUpdate, h, readTask } from '@stencil/core'; import { getIonMode } from '../../global/ionic-global'; import type { Color } from '../../interface'; @@ -172,11 +172,21 @@ export class Content implements ComponentInterface { } private resize() { - if (this.fullscreen) { - readTask(() => this.readDimensions()); - } else if (this.cTop !== 0 || this.cBottom !== 0) { - this.cTop = this.cBottom = 0; - forceUpdate(this); + /** + * Only force update if the component is rendered in a browser context. + * Using `forceUpdate` in a server context with pre-rendering can lead to an infinite loop. + * The `hydrateDocument` function in `@stencil/core` will render the `ion-content`, but + * `forceUpdate` will trigger another render, locking up the server. + * + * TODO: Remove if STENCIL-834 determines Stencil will account for this. + */ + if (Build.isBrowser) { + if (this.fullscreen) { + readTask(() => this.readDimensions()); + } else if (this.cTop !== 0 || this.cBottom !== 0) { + this.cTop = this.cBottom = 0; + forceUpdate(this); + } } }