Why is this not reactive? (using signal + html open attribute)

I have the following code:
const [openMenu, setOpenMenu] = createSignal<boolean>(false);

<details
class='dropdown'
onclick={() => setOpenMenu(!openMenu())}
open={openMenu()}
>
const [openMenu, setOpenMenu] = createSignal<boolean>(false);

<details
class='dropdown'
onclick={() => setOpenMenu(!openMenu())}
open={openMenu()}
>
Why is this not reactive? I need to click twice to actually show the menu. But then I cannot even close it anymore. Am I missing something here?
20 Replies
Grahf
Grahf6mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
𝔐𝔞𝔱𝔱𝔦𝔫
But what if it is synchronized on half of the clients? I don't wanna risk that, so I didn't implement it that way :/
Grahf
Grahf6mo ago
I'm not sure. Things I can think of to try include.... Using a create effect. Check the value of the signal in the create effect and set open on the details accordingly. Would need a ref for the details. Then I think it would be ref.open=true or false. Something like that. Or you could install nanostores or zustand. And use that to manage your state....guessing you don't want to do that. I wouldnt.
𝔐𝔞𝔱𝔱𝔦𝔫
Effect was not solid either. And I don't wanna include another state management library, as I chose solid because of that integration. I am currently using a ref, which works, but is not the way I wanted to go Well, sucks to be me.
peerreynders
peerreynders6mo ago
Ultimately the <details> element is driving the open behaviour, not the signal i.e. https://playground.solidjs.com/anonymous/a9113b4f-b0a5-4874-ae04-4f234b3822a3 i.e. you have to design around that fact. Failing that you have to author your own details component.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Grahf
Grahf6mo ago
Fancy
𝔐𝔞𝔱𝔱𝔦𝔫
Ok, thanks.
peerreynders
peerreynders6mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
𝔐𝔞𝔱𝔱𝔦𝔫
As far as I can see: the big difference in the corrected example is setTimeout(). Why would someone choose this approach over the other?
peerreynders
peerreynders6mo ago
The detail element is designed to work without any JavaScript so it claims autonomy. So in this case it may simply “not be for you”. The previous example used queueMicrotask - it turned out that the details open prop hadn't been updated by then so I had to wait until the next cycle of the event loop. I didn't try requestAnimationFrame().
𝔐𝔞𝔱𝔱𝔦𝔫
Aaah, neat trick. Will keep that one in mind, thanks a lot :D Also thanks for sharing that article ^^
Grahf
Grahf6mo ago
queueMicrotask doesn't wait for the next cycle of the event loop but setTimeout() does?
peerreynders
peerreynders6mo ago
The microtask queue is where resolved promises are scheduled - so (resolved) promises can block UI. setTimeout is considered a macrotask. https://vimeo.com/254947206
Grahf
Grahf6mo ago
I only ask because it feels like a question for a job interview. I could be wrong. event ,loop seems so abstract and people want you to know about it... Sorry didn't mena to hijack thread I will watch video 🙂
mdynnl
mdynnl6mo ago
why not e.preventDefault() + controls the open attribute by the signal?
peerreynders
peerreynders6mo ago
There was actually a 4ms minimum wait on setTimeout() to prevent client fingerprinting but they seemed to have eased up on that recently.
peerreynders
peerreynders6mo ago
Because one has to think of that first: https://playground.solidjs.com/anonymous/5894f9a2-aa5e-4106-b79d-aa2c843143bf Seriously people complain about Solid's documentation but I think MDN could benefit from more expansive examples as well.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
𝔐𝔞𝔱𝔱𝔦𝔫
@mdynnl @peerreynders Wow, thanks for that example! It fixed a sync problem between my child and parent! Nice!
Want results from more Discord servers?
Add your server