Strategies for not calling setters in effects

I'm helping train someone on the dos and donts of reactivity and I got stumped with a pretty basic question regarding calling setters in effects. Most of the time I'm able to design my reactivity to ensure I'm not calling a setter but there's one pattern that got me curious. Say I have a signal that exists at the root of the application. I want a child component deep down the tree to be able to temporarily effect that signal as an override. In my case when I display a modal I want the navigation elements on the page to be hidden then reappear when the modal is closed. This is basically what would seem like the only reasonable solution:
createEffect(()=>{
setHeaderVisible(props.open())
})
createEffect(()=>{
setHeaderVisible(props.open())
})
So when the prop on the component is truthy then set the header. This is a bit of a contrived example and I would typically do it differently but this explains the general idea. How does others avoid the setter in these situations?
15 Replies
davedbase
davedbaseOP2y ago
Ok, that's pretty much the conclusion I came to.
Otonashi
Otonashi2y ago
can't you set it when you open the modal?
davedbase
davedbaseOP2y ago
True but this is a contrived example. But good point Yeh but the set wouldn't be in an effect which goes back to just designing around using the setter in effect
thetarnav
thetarnav2y ago
can't you set it when you open the modal?
this can sometimes feel bad too reactivity is supposed to separate effects from causes but it's often the cleaner way after all
foolswisdom
foolswisdom2y ago
Generally, if you're doing this, we recommend using createComputed. And yes we want to deprecate it, but that's because we want to find a better way of handling this very case
davedbase
davedbaseOP2y ago
Yeah I discounted createComputed lol
foolswisdom
foolswisdom2y ago
You can't dislike createComputed because it was made to handle a usecase we don't like, and then proceed to handle the same use-case with a different primitive
thisbeyond
thisbeyond2y ago
I'm not particularly fussed about setters in effects. I believe they require more care to avoid loops and unintended side effects, but can be useful. For your specific example though I would choose to model state globally and derive from that. E.g the action that opens the model is setting some global state (state.activeModal), the modal then reacts to that to be shown and equally so can anything else (e.g. showHeader = () =>!state.activeModal)
davedbase
davedbaseOP2y ago
I personally want to know about the dangers of setters. Like a good reactive student I just accepted it was bad and abided. I wish @Jutanium would cover this in a video someday He should also quote me in the video to show he creates videos based on real discord rants :p
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
davedbase
davedbaseOP2y ago
I mean I was joking. If you just get me the answers I’d be happy regardless haha
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
ryansolid
ryansolid2y ago
Well.. safely in the fact you hope there are no side effects at that point but the reason we all dislike createComputed is because it does kill smart ordering. Effects writing Signals isn't great but it happens at the end.. you push them on to the end, its like starting over again
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
ryansolid
ryansolid2y ago
If you intend to only render something once making sure all the state is consistent before doing the heavy side effects is good. In createEffect is too late if you are thinking about synchronizing values The problem with createComputed isn't the timing, its just that in an ideal world everything at that point would be derived rather than written
Want results from more Discord servers?
Add your server