Open justinlovinger opened 4 years ago
Unless I am misunderstanding your question, this sort of parallel UI composition is already well supported by Concur. Have you tried using <|>
to compose the runCanvas
in parallel with the canvas UI element, and not letting the runCanvas
end by following it with empty
-
do
canvasId ← liftEffect random
canvas [ _id $ show canvasId ] []
<|> (liftEffect (runCanvas canvasId) *> empty)
Composing in parallel results in runCanvas
running before the canvas element exists, requiring an asyncronous wait loop. It is another workaround, but it still isn't as clean as something like an explicit onMount
callback.
Ah I see.
Synchronous actions are run "in-place" before populating the view, but asynchronous actions are run after the view is populated and stable, equivalent to doing it in componentDidMount
. So something like this might do the trick -
do
canvasId ← liftEffect random
canvas [ _id $ show canvasId ] []
<|> liftAff (liftEffect (runCanvas canvasId) *> empty)
Note that here we have pushed the empty
inside the Aff
. This makes sure that the Aff is not resolved synchronously.
Hmm, using liftAff
like that results in a runtime error:
Aff failed - parcelRequire<["output/Effect.Exception/foreign.js"]</exports.error@http://localhost:1234/e31bb0bc.js:19985:10
parcelRequire<["output/Effect.Aff/index.js"]<@http://localhost:1234/e31bb0bc.js:40984:73
newRequire@http://localhost:1234/e31bb0bc.js:47:24
localRequire@http://localhost:1234/e31bb0bc.js:53:14
parcelRequire<["output/Concur.Core.Types/index.js"]<@http://localhost:1234/e31bb0bc.js:42723:25
newRequire@http://localhost:1234/e31bb0bc.js:47:24
localRequire@http://localhost:1234/e31bb0bc.js:53:14
parcelRequire<["output/Component.Indicator/index.js"]<@http://localhost:1234/e31bb0bc.js:46325:32
newRequire@http://localhost:1234/e31bb0bc.js:47:24
localRequire@http://localhost:1234/e31bb0bc.js:53:14
parcelRequire<["output/Component.App/index.js"]<@http://localhost:1234/e31bb0bc.js:61772:34
newRequire@http://localhost:1234/e31bb0bc.js:47:24
localRequire@http://localhost:1234/e31bb0bc.js:53:14
parcelRequire<["output/Main/index.js"]<@http://localhost:1234/e31bb0bc.js:95989:28
newRequire@http://localhost:1234/e31bb0bc.js:47:24
localRequire@http://localhost:1234/e31bb0bc.js:53:14
parcelRequire<["index.js"]<@http://localhost:1234/e31bb0bc.js:96008:36
newRequire@http://localhost:1234/e31bb0bc.js:47:24
parcelRequire<@http://localhost:1234/e31bb0bc.js:81:17
@http://localhost:1234/e31bb0bc.js:120:3
Although, even if the runtime error is fixed, it still feels more like a workaround than intended behaviour. It's not clear from the code that liftAff
means "wait for the component to mount, then do this", and I think it is a common enough usecase to get proper support.
Hmm, that seems like a bug. I'm looking at it.
I'm trying to create a canvas element containing an animation, but I'm not sure how to compose the canvas itself with the render Effect.
With React, you can use a
componentDidMount
callback to render on a canvas, when the canvas is created in the dom. However, I don't see anything likeonComponentDidMount
.Currently, my solution looks like
This solution is not ideal for a few reasons. The
onClick
is just a placeholder to get therunCanvas
effect to run, and ending with a secondcanvas
feels like a hack.I have also considered starting an asyncronous effect with a wait loop, before calling the first
canvas
, but then I have an unnecessary wait loop and might leave orphan scripts.I'm not sure how to bundle a canvas element with it's corresponding render effect, without resorting to a workaround.