What's the reasoning behind removing DomSideEffect...
# compose-web
b
What's the reasoning behind removing DomSideEffect in 1.1.0? I find that ref {} is better suited for initialisation and destruction of the dom effects, while DomSideEffect was great for propagating compose state changes to external state. It's now doable with RefEffect, but onDispose lambda is pretty much always empty for me (which feels dirty).
o
What's the reasoning..
The idea behind that change in 1.1.0-... was to align with upstream compose's effects and reuse them rather than custom effects. For example, DisposableEffect api supports multiple keys and SideEffect supports no keys at all (unlike DomSideEffect).
It's now doable with RefEffect
it's also doable using DisposableEffect in the content of an element:
Copy code
DisposableEffect(key...) {
    scopeElement // this is a reference to an element
    onDispose {  } // onDispose is mandatory though
}
propagating compose state changes to external state
Compose's SideEffect can be used for that. I guess you want to have an access to an element reference within SideEffect, right? Could you please show some code snippet with effects where you want to access the reference?
b
Yeah, the main reason i can't reuse SideEffect is that I need access to native dom element.
My usecases are all accessing custom property I'm using to store external state on dom element itself
The reason why it's attached to dom element is that the external state needs a reference to dom element to initialise.
o
what's the meaning of
vararg keys: Any?
? Do they ever change in your case? I'm trying to think if we can provide a ref to an element within SideEffect (it doesn't have keys). Would it help you? Do you need those keys for some reason?
b
Ah, right. I need an effect that would run each time a key changes in order to update a custom dom element property (nested) with the key's value
So I guess SideEffect is not really an option here as it does not support keys.
o
then I guess DisposableEffect would be the best option if keys need to be involved. +DisposableEffect supports vararg key:.. so maybe forEach can be avoided here.
Copy code
public fun <MDC : MDCBaseModule.MDCComponent<*>> ElementScope<*>.MDCSideEffect(
  vararg keys: Any?,
  effect: Builder<MDC>
) {
  keys.forEach { key ->
    DomSideEffect(key) {
      it.mdc(effect)
    }
  }
}
as for accessing a reference in SideEffect, we'll think about it once again. Maybe even some sort of
__reallyUnsafeElementRef
could be added (still not very good I think).
b
I'm already replacing it with DisposableEffect, it's just that it feels wrong because I have nothing to dispose of here
o
some kind of AutoDisposableEffect would help avoid adding empty onDispose. But I'd prefer having it in common compose runtime, rather than only web.
b
I'm thinking about some new StateEffect or SyncEffect, which would be a side effect with keys (or disposable effect without disposal)
I can't be the only one with a usecase of key based syncs to external state
โž• 2
Just some ideas to ponder on. I'll stick with DisposableEffect for now.
Someone suggested LaunchedEffect for this. Could that one get access to dom element?
o
no, currently there is no access to dom element there. But we need to consider this as well. I'll ask around if LaunchedEffect is a good fit for sync purposes.
๐Ÿ‘ 1
b
Actually, looks like SideEffect is the best candidate for state sync up, as it's executed every recomposition caused by state change. The only missing piece for me is access to dom element.
o
yes, but as I understand you still want to have keys in SideEffect, right?
b
Ideally yes, but it's not that big of a deal having them to execute each recomposition. It's just suboptimal
๐Ÿ™ 1
๐Ÿ‘ 1
o
regarding LaunchedEffect. As I understand it doesn't have same property as SideEffect (ensuring the recomposition was successful) https://kotlinlang.slack.com/archives/CJLTWPH7S/p1630262216329100?thread_ts=1630261628.327800&amp;cid=CJLTWPH7S So while LaunchedEffect will likely work, it can be not as good as SideEffect in some rare circumstances (for some use cases).
๐Ÿ‘ 1
a
LaunchedEffect and DisposableEffect are both powered by RememberObserver and have the same property; they won't execute unless the composition is successful
๐Ÿ™ 1
I would need to look closer at how compose-web does or doesn't expose dom access currently to have a more informed opinion, but from reading this thread, what's different between what you're trying to do here and the composables calling ComposeNode?
b
I'm not familiar with ComposeNode
But I'll try to outline my case better with some examples later today once I'm back on my PC.
๐Ÿ‘ 1
Here's a minified example of my use-case with comments. Note thatย 
mdcComponent
ย is only attached to native DOM element because I couldn't think of a better way to make it accessible to the composition scope later on.
I think this is not just #compose-web specific use-case as other platforms should have a need for pinpointed external state sync.
d
Wow, TIL there's a side effect named after me.
๐Ÿ˜‚ 1
b
What? I seem to have missed the pun, apologies
d
Some people call me "Dom".
So
DomSideEffect
is named after me. ๐Ÿ™‚
b
Gotcha. Sorry you got deprecated ๐Ÿ˜€
๐Ÿ˜… 3
u
After reading all the feedback and discussing in the team weโ€™ve decided following things: 1. We leave DisposableRefEffect deprecated since DisposableEffect in combination with scopeElement seems to cover all needs and serves exactly for the purposes DisposableRefEffect was designed for. 2. Weโ€™ll thoroughly revisit our API and reconsider whether we should get rid of scopeElement in favour of approaches that are more common compose-idyomatic (but this investigation /designing process will take time) 3. Till further investigation and better proposal we undeprecate DomSideEffect.
๐Ÿ‘ 2
b
Congratz @Dominaezzz, you just got undeprecated ๐Ÿ˜€
๐Ÿ˜€ 6