bos-web-engine icon indicating copy to clipboard operation
bos-web-engine copied to clipboard

Components attempt to update sandboxed child Components before initialization

Open mpeterdev opened this issue 2 years ago • 2 comments

The following error messages appear in console when viewing the social feed demo

failed to send message to invalid iframe iframe-bwe-demos.near/Posts.Sidebar##left##bwe-demos.near/Posts.Feed {props: {…}, componentId: 'bwe-demos.near/Posts.Sidebar##left##bwe-demos.near/Posts.Feed', type: 'component.update'}

failed to send message to invalid iframe iframe-bwe-demos.near/Posts.Sidebar##right##bwe-demos.near/Posts.Feed {props: {…}, componentId: 'bwe-demos.near/Posts.Sidebar##right##bwe-demos.near/Posts.Feed', type: 'component.update'}

this was experienced on feat/application-restructure which is the most recent branch which successfully builds

mpeterdev avatar Dec 18 '23 19:12 mpeterdev

As discussed this is an extant issue on https://bos-web-engine.vercel.app/bwe-demos.near/Posts.Feed. It needs to be looked into but is not related to any unmerged work.

andy-haynes avatar Jan 02 '24 21:01 andy-haynes

In this case it looks like a race condition where the state is updated before the Component has rendered, i.e. before its container has initialized and the render request has been processed by the outer application. The order of operations here is:

  1. root Component is rendered
  2. root Component initiates a fetch via useEffect
  3. sandboxed child Components are fetched
  4. root Component's fetch completes, updating its state and triggering a re-render
  5. root Component re-renders, requesting that its sandboxed children, whose containers are not registered at this point, are also requested to update - resulting in the invalid iframe error
  6. child Component completes initialization and requests a render, at which point the iframe container is registered and subsequent updates are valid

One solution would be to defer these updates until after the Component has rendered, enqueuing them until the container is registered and can receive update requests. This could be further optimized by deferring the lookup of container-level props when rendering SandboxedIframe components.

This handles two scenarios in which the parent Component re-renders before its sandboxed child Component's container is initialized: either before the child iframe is rendered, when the Component tree is still being processed, or after the iframe is rendered, but before the iframe container's root Component has requested its initial render. E.g.:

  • parent re-renders before the child's iframe is rendered: override the current props in a new container props registry so that the latest props are used when the child iframe is rendered
  • parent re-renders after child's iframe is rendered but before the iframe has initialized: queue the update to be applied after the render is complete

Only the latter needs to be implemented for a working solution, but the former case seems much more likely since processing the Component tree is often more involved than rendering it.

andy-haynes avatar Jan 03 '24 00:01 andy-haynes