MVCoconut / coconut.ui

Wow, such reactive view! Much awesome!
The Unlicense
89 stars 9 forks source link

`@:computed` depending on `@:ref` stops working when ref changes #54

Closed Antriel closed 4 years ago

Antriel commented 4 years ago
@:ref var something:Something; 
@:computed var boink:Boink = something.boink; //stops updating when `something` changes
function render() '<Something ref=${something} />';

Workaround:

@:state var something:Something = null;
@:computed var boink:Boink = something.boink; 
function render() '<Something ref=${v -> something = v} />';
back2dos commented 4 years ago

Hmm. After some thinking, I'm inclined to say that you shouldn't be doing any such thing at all.

This way, diffing will cause invalidation (the workaround does and so would the code that you would like to work). That's asking for trouble.

If you wish to share state between a parent and a child like this, then you'll have to lift it up to the parent.

@:state var boink:Boink = someBoink;
function render() '<Something boink=$boink />';

If you need the child to change the shared state, you can either pass callbacks down to the child, or use controlled attributes:

class Something extends View {
  @:controlled var boink:Boink;
}
back2dos commented 4 years ago

Alternatively, the logic around the shared state can also be extracted into a model that properly encapsulates it and then that model can be shared between parent and child.