Say you have three nested components. GrandParent
-> Parent
-> Child
. You have state(foo
and bar
) that lives in Grandparent
. That state is then changed by something that happens in Child
. There are two different ways to think about how to get this state to change, Event Emitting and Callback passing. I think it would be wise of us to consider switching to a callback approach rather than an Event Emitting. Primarily because I think it reduces unneccessary boilerplate and having to write logic in the "middle man" component, which in this case is the parent.
Here is the code for the two different approaches. Let me know what you think
{namespace GrandParent}
/**
* GrandParent
*/
{template .render}
{call Parent.render}
{param events: [
'childFooChange': $_handleNewFoo,
'childBarChange': $_handleNewBar
] /}
{/call}
{/template}
class GrandParent extends Component {
_handleNewFoo(newFoo) {
this.state.foo = newFoo;
}
_handleNewBar(newBar) {
this.state.bar = newBar;
}
}
{namespace Parent}
/**
* Parent
*/
{template .render}
{call Child.render}
{param events: [
'fooChange': $_handleFooChange,
'barChange': $_handleBarChange
] /}
{/call}
{/template}
class Parent extends Component {
_handleFooChange(event) {
this.emit('childFooChange', event);
}
_handleBarChange() {
this.emit('childBarChange', event);
}
}
{namespace GrandParent}
/**
* GrandParent
*/
{template .render}
{call Parent.render}
{param onChildFooChange: $_handleNewFoo /}
{param onChildBarChange: $_handleNewBar /}
{/call}
{/template}
class GrandParent extends Component {
_handleNewFoo(newFoo) {
this.state.foo = newFoo;
}
_handleNewBar(newBar) {
this.state.bar = newBar;
}
}
{namespace Parent}
/**
* Parent
*/
{template .render}
{@param onChildFooChange: any}
{@param onChildBarChange: any}
{call Child.render}
{param onFooChange: $onChildFooChange /}
{param onBarChange: $onChildBarChange /}
{/call}
{/template}
class Parent extends Component {
// No need to emit anything anymore
}
I think using callbacks are easier to debug and easier to reason about when reading through code. This is especially helpful when there are multiple components nested, otherwise you would be creating event emitters on each component up the tree. This is a common pattern used in React and a pattern we picked up and used in Loop. We found is extremely helpful and easy to work with since it follows the same paradigm as passing down state
through components.
Let me know what you think!
A parrot for your time.
Hi!
Since the event emitting stack is preserved and you can follow the calls to the original emitter, for me debugging events or callbacks is mostly the same.
For me the events way makes components feel a little more independent, but I guess that's just a matter of taste.
Also, events way gives you the option of listening some events for free, like:
With this you're listening the button click without needing to add any logic, callback execution or extra event emitting on button component.
But to decide this... I will go for the reason of not rewrite everything to switch to callbacks...
What do you guys think? 😃