Fork me on GitHub
#rum
<
2020-09-03
>
cmdrdats08:09:53

TIL: rum/local adds its own watcher and forces update on the component. Leads to unexpected rerendering when you're actually only using the local state as coordination between children components.

cmdrdats08:09:46

This is what I expected rum/local implementation to be..

joe-withey12:09:04

That wouldn't cause a rerender when the state changes though would it?

cmdrdats13:09:44

no, but if you wanted that, you'd rum/reactive on the component and rum/react the local atom - as you'd any other atom

cmdrdats13:09:03

contrived example: the parent atom here coordinates two children - when you click the button only the local-view should re-render and get a new value. the rand-int on the button and parent shouldn't fire.

cmdrdats13:09:13

at least, my intuition of rum/local says it shouldn't. But I'm wrong, and I don't imagine this can get changed without serious backward breaking problems.

joe-withey18:09:32

Thinking of how react works, the button needs to re render to capture the new value of the val-atom in it's closure. In react both components would re-render, I think rum/local is supposed to work in a similar manner to useState or this.state in react...

joe-withey18:09:21

Ah but I guess val-atom is a ref, maybe if you used the rum/static mixin on button it would not re-render every time it's props change as the ref passed as a prop would be equivalent?

joe-withey18:09:49

Also I think rum/react is used exclusively with clojurescript atoms, not rum/local state, you can just deref local state with @val-atom

joe-withey18:09:23

This is what I'm suggesting, although I would probably create a function in parent to perform the swap! in the scope of where the local state is defined and just pass that to the button to bind it to the on-click handler of the nested :button, I don't think passing around atoms is a good idea but I'm quite new to rum, that's more of a habit from working with react in JS.

cmdrdats07:09:43

so, rum/local is exactly a clojurescript atom that you mix in, since it needs to generate for local scope on will-mount . I reckon the rule should be consistent: if you want your component to react to any state change, use rum/react - just a deref should always be assumed to be wrong (unless you specifically don't care about the reaction/update, that is)

cmdrdats07:09:14

passing around atoms and cursors, in my experience of rum at least, is completely normal and useful - but that's not really the point here. I'm more saying that the default behaviour of rum/local mixing in an implicit rum/reactive and rum/react for its atom can be unexpected.. - of course, I've worked around it by implementing my own simplified version of rum/local which we'll be using ubiquitously, but I mention it here as something for people to be aware of.

joe-withey08:09:31

If you look at https://github.com/tonsky/rum/blob/gh-pages/src/rum/core.cljs#L335 It seems to indicate that derefing a rum/local state is fine in the docstring, and that rum/react is intended to be used with rum/reactive

cmdrdats09:09:59

yes - I'm saying that the current implementation of rum/local is unexpected. it "works" to just deref, but it's treated as not only a local atom, but also an implicit local rum/reactive - see the duplication: https://github.com/tonsky/rum/blob/gh-pages/src/rum/core.cljs#L353 and https://github.com/tonsky/rum/blob/gh-pages/src/rum/core.cljs#L394 - imo, the rum/local 's single job should be to provide a local component scoped atom that you can change. Its job should not be to also rerender the component if the atom changes.

didibus08:09:45

Ya I agree with you, it's confusing

didibus08:09:34

It makes sense for the use case of a component changing its own state, or wanting to share some atom with other components that will update the atom to change them

didibus08:09:03

But definitely a bit confusing when you just want state, and not want reactivity

didibus08:09:01

Would have been clearer to make it a normal local. And then if you want reactivity also make the component reactive and use react on the local

cmdrdats08:09:51

ye, that's what I would have expected - I've made my own version of rum/local and changing all our usecases to that, since we rum/react on everything (even local atoms) already.