HalogenIO.dispose doesn't remove Hook-based components
JordanMartinez opened this issue · 4 comments
Compare these two implementations of a component that loads and is removed after 2 seconds via HalogenIO.dispose
:
The Halogen
one removes 'Loading' from the page whereas the Hook
one does not.
This problem still exists even when I make the Hook component a render-only component, which tells me Hooks.fork
isn't an issue here:
loading :: forall q i o. H.Component HH.HTML q i o Aff
loading = Hooks.component \_ _ ->
Hooks.pure $
HH.h1_
[ HH.text $ "Loading" ]
I don't yet know why HalogenIO.dispose
doesn't remove the hook-based component. For anyone who runs into this bug before it's ironed out -- if you need to use dispose
at the top level, then keep in mind that ordinary Halogen components are properly disposed of. So long as the root component is a normal Halogen component you are OK.
I took a look at this over lunch. This is a bug in Halogen in which dispose
tries to remove the VDom tree that existed when the root component was initialized, not the one that exists when it is disposed of.
This ordinarily isn't a big problem -- dispose
removes the root of the VDom tree, and for your root component that probably hasn't changed over the lifetime of your application. But Hooks-based components first render an empty text node and only render your desired HTML after the first Hooks evaluation. That means dispose
will always fail on a Hooks component due to the bug in Halogen's dispose
implementation.
purescript-halogen/purescript-halogen#675 describes this issue and purescript-halogen/purescript-halogen#676 fixes it.
You can see via this Try PureScript reproduction that this isn't a Hooks-only problem -- it's a problem for any Halogen component that renders a different root element after its first render:
https://try.purescript.org/?gist=4c7f24a18ac9120b715c95b0b769d3f9
Closing as this is fixed as of Halogen's v5.0.2 release.
Nice investigative work there!